KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > update > internal > operations > FeatureHierarchyElement


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.operations;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Set JavaDoc;
15
16 import org.eclipse.core.runtime.*;
17 import org.eclipse.update.configuration.*;
18 import org.eclipse.update.core.*;
19 import org.eclipse.update.internal.core.*;
20
21 /**
22  * This class is used to construct a joint feature hiearchy.
23  * Old feature reference represents feature that is
24  * found on in the current configuration. New feature
25  * reference is found in the feature that is an install/update
26  * candidate. The element is used to join nodes of the
27  * hiearchy formed by including features so that
28  * each node in the hiearchy contains references to the
29  * old and the new feature. Old and new features have
30  * the same IDs but different versions, except in
31  * the case of optional features, where the tree may
32  * be constructed to bring in an optional feature
33  * that was not installed initially. In that case,
34  * some nodes may have old an new references with the
35  * same ID and version.
36  * <p>
37  * Old feature reference may be null. That means
38  * that the older feature with the same ID but lower
39  * version was not found in the current configuration.
40  */

41 public class FeatureHierarchyElement {
42
43     private Object JavaDoc root;
44     private ArrayList JavaDoc children;
45     private IFeatureReference oldFeatureRef;
46     private IFeatureReference newFeatureRef;
47     private boolean checked;
48     private boolean optionalChildren;
49     private boolean nativeUpgrade = false;
50
51     public FeatureHierarchyElement(
52         IFeatureReference oldRef,
53         IFeatureReference newRef) {
54         oldFeatureRef = oldRef;
55         newFeatureRef = newRef;
56     }
57
58     public void setRoot(Object JavaDoc root) {
59         this.root = root;
60     }
61
62     public Object JavaDoc getRoot() {
63         return root;
64     }
65
66     /*
67      * Return true if element can be checked, false otherwise.
68      */

69     public boolean isEditable() {
70         // cannot uncheck non-optional features
71
if (isOptional() == false)
72             return false;
73         // cannot uncheck optional feature that
74
// has already been installed
75
if (oldFeatureRef != null)
76             return false;
77         return true;
78     }
79
80     /**
81      * A hirearchy node represents a 'false update' if
82      * both old and new references exist and both
83      * point to the feature with the same ID and version.
84      * These nodes will not any bytes to be downloaded -
85      * they simply exist to allow the hirarchy to
86      * reach the optional children that are missing
87      * and will be installed.
88      */

89
90     public boolean isFalseUpdate() {
91         if (oldFeatureRef != null && newFeatureRef != null) {
92             try {
93                 return oldFeatureRef.getVersionedIdentifier().equals(
94                     newFeatureRef.getVersionedIdentifier());
95             } catch (CoreException e) {
96             }
97         }
98         return false;
99     }
100     /**
101      * Returns true if feature is included as optional.
102      */

103     public boolean isOptional() {
104         return newFeatureRef instanceof IIncludedFeatureReference
105             && ((IIncludedFeatureReference) newFeatureRef).isOptional();
106     }
107     /**
108      * Returns true if this optional feature is selected
109      * for installation. Non-optional features or non-editable
110      * features are always checked.
111      */

112     public boolean isChecked() {
113         return checked;
114     }
115
116     void setNativeUpgrade(boolean nativeUpgrade) {
117         this.nativeUpgrade = nativeUpgrade;
118     }
119
120     /**
121      * Returns true if this optional feature should
122      * be enabled when installed. By default, all
123      * features in the hiearchy should be enabled.
124      * The exception is for optional features that
125      * are updated to a new version in case where
126      * the older version of the optional feature
127      * is disabled in the given configuration.
128      * In this case, the feature is
129      * updated and disabled in order to maintain
130      * its state.
131      */

132     public boolean isEnabled(IInstallConfiguration config) {
133         if (nativeUpgrade)
134             return true;
135         if (isOptional() && oldFeatureRef != null) {
136             try {
137                 IFeature oldFeature = oldFeatureRef.getFeature(null);
138                 IConfiguredSite csite =
139                     UpdateUtils.getConfigSite(oldFeature, config);
140                 return csite.isConfigured(oldFeature);
141             } catch (CoreException e) {
142             }
143         }
144         return true;
145     }
146
147     public IFeature getFeature() {
148         try {
149             IFeature feature = newFeatureRef.getFeature(null);
150             return feature;
151         } catch (CoreException e) {
152             return null;
153         }
154     }
155
156     /**
157      * Selects an editable feature for installation.
158      */

159     public void setChecked(boolean checked) {
160         this.checked = checked;
161     }
162     /**
163      * Returns label for UI presentation.
164      */

165     public String JavaDoc getLabel() {
166         try {
167             return getFeatureLabel(newFeatureRef);
168         } catch (CoreException e) {
169             if (newFeatureRef instanceof IIncludedFeatureReference) {
170                 String JavaDoc iname =
171                     ((IIncludedFeatureReference) newFeatureRef).getName();
172                 if (iname != null)
173                     return iname;
174             }
175             try {
176                 VersionedIdentifier vid =
177                     newFeatureRef.getVersionedIdentifier();
178                 return vid.toString();
179             } catch (CoreException e2) {
180             }
181         }
182         return null;
183     }
184     /**
185      * Computes label from the feature.
186      */

187     private String JavaDoc getFeatureLabel(IFeatureReference featureRef)
188         throws CoreException {
189         IFeature feature = featureRef.getFeature(null);
190         return feature.getLabel()
191             + " " //$NON-NLS-1$
192
+ feature.getVersionedIdentifier().getVersion().toString();
193     }
194     /**
195      * Computes children by linking matching features from the
196      * old feature's and new feature's hierarchy.
197      */

198     public FeatureHierarchyElement[] getChildren(
199         boolean update,
200         boolean patch,
201         IInstallConfiguration config) {
202         computeChildren(update, patch, config);
203         FeatureHierarchyElement[] array =
204             new FeatureHierarchyElement[children.size()];
205         children.toArray(array);
206         return array;
207     }
208
209     public FeatureHierarchyElement[] getChildren() {
210         if (children != null) {
211             FeatureHierarchyElement[] array =
212                 new FeatureHierarchyElement[children.size()];
213             children.toArray(array);
214             return array;
215         }
216
217         return new FeatureHierarchyElement[0];
218     }
219     /**
220      * Computes children of this node.
221      */

222     public void computeChildren(
223         boolean update,
224         boolean patch,
225         IInstallConfiguration config) {
226         if (children == null) {
227             children = new ArrayList JavaDoc();
228             try {
229                 IFeature oldFeature = null;
230                 IFeature newFeature = null;
231                 newFeature = newFeatureRef.getFeature(null);
232                 if (oldFeatureRef != null)
233                     oldFeature = oldFeatureRef.getFeature(null);
234                 optionalChildren =
235                     computeElements(
236                         oldFeature,
237                         newFeature,
238                         update,
239                         patch,
240                         config,
241                         children);
242                 for (int i = 0; i < children.size(); i++) {
243                     FeatureHierarchyElement element =
244                         (FeatureHierarchyElement) children.get(i);
245                     element.setRoot(getRoot());
246                 }
247             } catch (CoreException e) {
248             }
249         }
250     }
251     /**
252      *
253      */

254     public boolean hasOptionalChildren() {
255         return optionalChildren;
256     }
257     /**
258      * Adds checked optional features to the provided set.
259      */

260     public void addCheckedOptionalFeatures(
261         boolean update,
262         boolean patch,
263         IInstallConfiguration config,
264         Set JavaDoc set) {
265         if (isOptional() && isChecked()) {
266             // Do not add checked optional features
267
// if this is an update case but
268
// the node is not a 'true' update
269
// (old and new feature are the equal)
270
if (!update || !isFalseUpdate())
271                 set.add(newFeatureRef);
272         }
273         FeatureHierarchyElement[] elements = getChildren(update, patch, config);
274         for (int i = 0; i < elements.length; i++) {
275             elements[i].addCheckedOptionalFeatures(update, patch, config, set);
276         }
277     }
278
279     /**
280      * Computes first-level children of the linked hierarchy
281      * for the provided old and new features (same ID, different version
282      * where new version is greater or equal the old version).
283      * Old feature may be null.
284      */

285     public static boolean computeElements(
286         IFeature oldFeature,
287         IFeature newFeature,
288         boolean update,
289         boolean patch,
290         IInstallConfiguration config,
291         ArrayList JavaDoc list) {
292         Object JavaDoc[] oldChildren = null;
293         Object JavaDoc[] newChildren = getIncludedFeatures(newFeature);
294         boolean optionalChildren = false;
295
296         try {
297             if (oldFeature != null) {
298                 oldChildren = getIncludedFeatures(oldFeature);
299             }
300             for (int i = 0; i < newChildren.length; i++) {
301                 IFeatureReference oldRef = null;
302                 IFeatureReference newRef = (IFeatureReference) newChildren[i];
303                 if (oldChildren != null) {
304                     String JavaDoc newId =
305                         newRef.getVersionedIdentifier().getIdentifier();
306
307                     for (int j = 0; j < oldChildren.length; j++) {
308                         IFeatureReference cref =
309                             (IFeatureReference) oldChildren[j];
310                         try {
311                             if (cref
312                                 .getVersionedIdentifier()
313                                 .getIdentifier()
314                                 .equals(newId)) {
315                                 oldRef = cref;
316                                 break;
317                             }
318                         } catch (CoreException ex) {
319                         }
320                     }
321                 } else if (patch) {
322                     // 30849 - find the old reference in the
323
// configuration.
324
if (!UpdateUtils.isPatch(newFeature)) {
325                         oldRef = findPatchedReference(newRef, config);
326                     }
327                 }
328                 // test if the old optional feature exists
329
if (oldRef != null
330                     && ((oldRef instanceof IIncludedFeatureReference
331                         && ((IIncludedFeatureReference) oldRef).isOptional())
332                         || patch)) {
333                     try {
334                         IFeature f = oldRef.getFeature(null);
335                         if (f == null)
336                             oldRef = null;
337                     } catch (CoreException e) {
338                         // missing
339
oldRef = null;
340                     }
341                 }
342                 FeatureHierarchyElement element =
343                     new FeatureHierarchyElement(oldRef, newRef);
344                 // If this is an update (old feature exists),
345
// only check the new optional feature if the old exists.
346
// Otherwise, always check.
347
if (element.isOptional() && (update || patch)) {
348                     element.setChecked(oldRef != null);
349                     if (oldRef == null) {
350                         // Does not have an old reference,
351
// but it may contain an older
352
// feature that may still qualify
353
// for update. For example,
354
// an older version may have been
355
// installed natively from the CD-ROM.
356
if (hasOlderVersion(newRef)) {
357                             element.setNativeUpgrade(true);
358                             element.setChecked(true);
359                         }
360                     }
361                 } else
362                     element.setChecked(true);
363                 list.add(element);
364                 element.computeChildren(update, patch, config);
365                 if (element.isOptional() || element.hasOptionalChildren())
366                     optionalChildren = true;
367             }
368         } catch (CoreException e) {
369         }
370         return optionalChildren;
371     }
372     public static boolean hasOlderVersion(IFeatureReference newRef) {
373         try {
374             VersionedIdentifier vid = newRef.getVersionedIdentifier();
375             PluginVersionIdentifier version = vid.getVersion();
376             String JavaDoc mode = getUpdateVersionsMode();
377
378             IFeature[] allInstalled =
379                 UpdateUtils.getInstalledFeatures(vid, false);
380             for (int i = 0; i < allInstalled.length; i++) {
381                 IFeature candidate = allInstalled[i];
382                 PluginVersionIdentifier cversion =
383                     candidate.getVersionedIdentifier().getVersion();
384                 // Verify that the difference qualifies as
385
// an update.
386
if (mode.equals(UpdateCore.EQUIVALENT_VALUE)) {
387                     if (version.isEquivalentTo(cversion))
388                         return true;
389                 } else if (mode.equals(UpdateCore.COMPATIBLE_VALUE)) {
390                     if (version.isCompatibleWith(cversion))
391                         return true;
392                 }
393             }
394         } catch (CoreException e) {
395         }
396         return false;
397     }
398
399     private static IFeatureReference findPatchedReference(
400         IFeatureReference newRef,
401         IInstallConfiguration config)
402         throws CoreException {
403         VersionedIdentifier vid = newRef.getVersionedIdentifier();
404         IConfiguredSite[] csites = config.getConfiguredSites();
405         for (int i = 0; i < csites.length; i++) {
406             IConfiguredSite csite = csites[i];
407             IFeatureReference[] refs = csite.getConfiguredFeatures();
408             for (int j = 0; j < refs.length; j++) {
409                 IFeatureReference ref = refs[j];
410                 VersionedIdentifier refVid = ref.getVersionedIdentifier();
411                 if (vid.getIdentifier().equals(refVid.getIdentifier()))
412                     return ref;
413             }
414         }
415         return null;
416     }
417
418     /**
419      * Returns included feature references for the given reference.
420      */

421     public static Object JavaDoc[] getIncludedFeatures(IFeatureReference ref) {
422         try {
423             IFeature feature = ref.getFeature(null);
424             return getIncludedFeatures(feature);
425         } catch (CoreException e) {
426         }
427         return new Object JavaDoc[0];
428     }
429
430     /**
431      * Returns included feature references for the given feature.
432      */

433
434     public static Object JavaDoc[] getIncludedFeatures(IFeature feature) {
435         try {
436             return feature.getIncludedFeatureReferences();
437         } catch (CoreException e) {
438         }
439         return new Object JavaDoc[0];
440     }
441
442     private static String JavaDoc getUpdateVersionsMode() {
443         Preferences store = UpdateCore.getPlugin().getPluginPreferences();
444         return store.getString(UpdateCore.P_UPDATE_VERSIONS);
445     }
446 }
447
Popular Tags