KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > core > FeatureModelManager


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.pde.internal.core;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.Set JavaDoc;
17
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.pde.core.IModel;
20 import org.eclipse.pde.core.IModelProviderEvent;
21 import org.eclipse.pde.core.IModelProviderListener;
22 import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
23 import org.eclipse.pde.internal.core.util.VersionUtil;
24 import org.osgi.framework.Version;
25
26 /**
27  * Manages all feature models in the workspace, and maximum one external feature
28  * model for a given id and version. While workspace model(s) exist with the
29  * same id and version as an external model, the external model is inactive (not
30  * exposed).
31  */

32
33 public class FeatureModelManager {
34
35     /**
36      * All models in workspace, and those external models that have no
37      * corresponding workspace model with the same id and version
38      */

39     private FeatureTable fActiveModels;
40
41     /**
42      * External models masked by workspace models with the same id and version.
43      */

44     private FeatureTable fInactiveModels;
45
46     private ExternalFeatureModelManager fExternalManager;
47     
48     private boolean fReloadExternalNeeded = false;
49
50     private WorkspaceFeatureModelManager fWorkspaceManager;
51
52     private IModelProviderListener fProviderListener;
53
54     /**
55      * List of IFeatureModelListener
56      */

57     private ArrayList JavaDoc fListeners;
58
59     public FeatureModelManager() {
60         fWorkspaceManager = new WorkspaceFeatureModelManager();
61         fListeners = new ArrayList JavaDoc();
62     }
63
64     public synchronized void shutdown() {
65         if (fWorkspaceManager != null)
66             fWorkspaceManager.removeModelProviderListener(fProviderListener);
67         if (fExternalManager != null){
68             fExternalManager.removeModelProviderListener(fProviderListener);
69             fExternalManager.shutdown();
70         }
71     }
72
73     private synchronized void init() {
74         if (fActiveModels != null) {
75             if (fReloadExternalNeeded) {
76                 fReloadExternalNeeded = false;
77                 fExternalManager.reload();
78             }
79             return;
80         }
81         
82         fActiveModels = new FeatureTable();
83         fInactiveModels = new FeatureTable();
84         
85         fProviderListener = new IModelProviderListener() {
86             public void modelsChanged(IModelProviderEvent e) {
87                 handleModelsChanged(e);
88             }
89         };
90         fWorkspaceManager.addModelProviderListener(fProviderListener);
91
92         IFeatureModel[] models = fWorkspaceManager.getFeatureModels();
93         for (int i = 0; i < models.length; i++) {
94             // add all workspace models, including invalid or duplicate (save
95
// id, ver)
96
fActiveModels.add(models[i]);
97         }
98
99         fExternalManager = new ExternalFeatureModelManager();
100         fExternalManager.addModelProviderListener(fProviderListener);
101         fReloadExternalNeeded = false;
102         fExternalManager.startup();
103     }
104
105     /*
106      * @return all active features
107      */

108     public IFeatureModel[] getModels() {
109         init();
110         IFeatureModel[] allModels = fActiveModels.getAll();
111         ArrayList JavaDoc valid = new ArrayList JavaDoc(allModels.length);
112         for( int i =0; i< allModels.length; i++){
113             if(allModels[i].isValid()){
114                 valid.add(allModels[i]);
115             }
116         }
117         return (IFeatureModel[])valid.toArray(new IFeatureModel[valid.size()]);
118     }
119     
120     public IFeatureModel[] getWorkspaceModels() {
121         init();
122         return fWorkspaceManager.getFeatureModels();
123     }
124     
125     public IFeatureModel getFeatureModel(IProject project) {
126         init();
127         return fWorkspaceManager.getFeatureModel(project);
128     }
129
130     /**
131      * Finds active model with a given id and version
132      *
133      * @param id
134      * @param version
135      * @return one IFeature model or null
136      */

137     public IFeatureModel findFeatureModel(String JavaDoc id, String JavaDoc version) {
138         init();
139         IFeatureModel[] models = fActiveModels.get(id, version);
140         for (int i = 0; i < models.length; i++) {
141             if (models[i].isValid()) {
142                 return models[i];
143             }
144         }
145         if (models.length == 0 && "0.0.0".equals(version)) { //$NON-NLS-1$
146
return findFeatureModel(id);
147         }
148         return null;
149     }
150
151     /**
152      * Finds active model with the given id and version. If feature is not
153      * found, but a feature with qualifier set to qualifier exists it will be
154      * returned.
155      *
156      * @param id
157      * @param version
158      * @return IFeatureModel or null
159      */

160     public IFeatureModel findFeatureModelRelaxed(String JavaDoc id, String JavaDoc version) {
161         IFeatureModel model = findFeatureModel(id, version);
162         if (model != null) {
163             return model;
164         }
165         Version pvi = Version.parseVersion(version);
166         return findFeatureModel(id, pvi.getMajor() + "." //$NON-NLS-1$
167
+ pvi.getMinor() + "." //$NON-NLS-1$
168
+ pvi.getMicro() + ".qualifier"); //$NON-NLS-1$
169
}
170
171     /**
172      * Finds active models with a given id
173      *
174      * @param id
175      * @param version
176      * @return IFeature model[]
177      */

178     public IFeatureModel[] findFeatureModels(String JavaDoc id) {
179         init();
180         IFeatureModel[] models = fActiveModels.get(id);
181         ArrayList JavaDoc valid = new ArrayList JavaDoc(models.length);
182         for( int i =0; i< models.length; i++){
183             if(models[i].isValid()){
184                 valid.add(models[i]);
185             }
186         }
187         return (IFeatureModel[])valid.toArray(new IFeatureModel[valid.size()]);
188     }
189     
190     public IFeatureModel findFeatureModel(String JavaDoc id) {
191         IFeatureModel[] models = findFeatureModels(id);
192         IFeatureModel model = null;
193         for (int i = 0; i < models.length; i++) {
194             if (model == null) {
195                 model = models[i];
196             } else {
197                 String JavaDoc version = model.getFeature().getVersion();
198                 String JavaDoc version2 = models[i].getFeature().getVersion();
199                 Version vid = Version.parseVersion(version);
200                 Version vid2 = Version.parseVersion(version2);
201                 if (VersionUtil.isGreaterOrEqualTo(vid2, vid)) {
202                     model = models[i];
203                 }
204             }
205         }
206         return model;
207     }
208
209     private void handleModelsChanged(IModelProviderEvent e) {
210         init();
211         IFeatureModelDelta delta = processEvent(e);
212
213         Object JavaDoc[] entries = fListeners.toArray();
214         for (int i = 0; i < entries.length; i++) {
215             ((IFeatureModelListener) entries[i]).modelsChanged(delta);
216         }
217     }
218
219     /**
220      * @param e
221      * @return
222      */

223     private synchronized IFeatureModelDelta processEvent(IModelProviderEvent e) {
224         FeatureModelDelta delta = new FeatureModelDelta();
225         /*
226          * Set of Idvers for which there might be necessary to move a model
227          * between active models and inactive models
228          */

229         Set JavaDoc affectedIdVers = null;
230         if ((e.getEventTypes() & IModelProviderEvent.MODELS_REMOVED) != 0) {
231             IModel[] removed = e.getRemovedModels();
232             for (int i = 0; i < removed.length; i++) {
233                 if (!(removed[i] instanceof IFeatureModel))
234                     continue;
235                 IFeatureModel model = (IFeatureModel) removed[i];
236                 FeatureTable.Idver idver = fActiveModels.remove(model);
237                 if (idver != null) {
238                     // may need to activate another model
239
if (affectedIdVers == null)
240                         affectedIdVers = new HashSet JavaDoc();
241                     affectedIdVers.add(idver);
242                     delta.add(model, IFeatureModelDelta.REMOVED);
243                 } else {
244                     fInactiveModels.remove(model);
245                 }
246             }
247         }
248         if ((e.getEventTypes() & IModelProviderEvent.MODELS_ADDED) != 0) {
249             IModel[] added = e.getAddedModels();
250             for (int i = 0; i < added.length; i++) {
251                 if (!(added[i] instanceof IFeatureModel))
252                     continue;
253                 IFeatureModel model = (IFeatureModel) added[i];
254                 if (model.getUnderlyingResource() != null) {
255                     FeatureTable.Idver idver = fActiveModels.add(model);
256                     delta.add(model, IFeatureModelDelta.ADDED);
257                     // may need to deactivate another model
258
if (affectedIdVers == null)
259                         affectedIdVers = new HashSet JavaDoc();
260                     affectedIdVers.add(idver);
261                 } else {
262                     if (!model.isValid()) {
263                         // ignore invalid external models
264
continue;
265                     }
266                     String JavaDoc id = model.getFeature().getId();
267                     String JavaDoc version = model.getFeature().getVersion();
268                     if (fInactiveModels.get(id, version).length > 0) {
269                         // ignore duplicate external models
270
continue;
271                     }
272                     IFeatureModel[] activeModels = fActiveModels.get(id,
273                             version);
274                     for (int j = 0; j < activeModels.length; j++) {
275                         if (activeModels[j].getUnderlyingResource() == null) {
276                             // ignore duplicate external models
277
continue;
278                         }
279                     }
280                     FeatureTable.Idver idver = fInactiveModels.add(model);
281                     // may need to activate this model
282
if (affectedIdVers == null)
283                         affectedIdVers = new HashSet JavaDoc();
284                     affectedIdVers.add(idver);
285                 }
286             }
287         }
288
289         /* 1. Reinsert with a new id and version, if necessary */
290         if ((e.getEventTypes() & IModelProviderEvent.MODELS_CHANGED) != 0) {
291             IModel[] changed = e.getChangedModels();
292             for (int i = 0; i < changed.length; i++) {
293                 if (!(changed[i] instanceof IFeatureModel))
294                     continue;
295                 IFeatureModel model = (IFeatureModel) changed[i];
296
297                 String JavaDoc id = model.getFeature().getId();
298                 String JavaDoc version = model.getFeature().getVersion();
299
300                 FeatureTable.Idver oldIdver = fActiveModels.get(model);
301                 if (oldIdver != null && !oldIdver.equals(id, version)) {
302                     // version changed
303
FeatureTable.Idver idver = fActiveModels.add(model);
304                     if (affectedIdVers == null)
305                         affectedIdVers = new HashSet JavaDoc();
306                     affectedIdVers.add(oldIdver);
307                     affectedIdVers.add(idver);
308                 }
309                 /*
310                  * no need to check inactive models, because external features
311                  * do not chance or version
312                  */

313
314             }
315         }
316         /* 2. Move features between active and inactive tables if necessary */
317         adjustExternalVisibility(delta, affectedIdVers);
318         /*
319          * 3. Changed models that do result in FeatureModelDelta.ADDED or
320          * FeatureModelDelta.Removed fire FeatureModelDelta.CHANGED
321          */

322         if ((e.getEventTypes() & IModelProviderEvent.MODELS_CHANGED) != 0) {
323             IModel[] changed = e.getChangedModels();
324             for (int i = 0; i < changed.length; i++) {
325                 if (!(changed[i] instanceof IFeatureModel))
326                     continue;
327                 IFeatureModel model = (IFeatureModel) changed[i];
328                 if (!delta.contains(model, IFeatureModelDelta.ADDED
329                         | IFeatureModelDelta.REMOVED)) {
330                     delta.add(model, IFeatureModelDelta.CHANGED);
331                 }
332
333             }
334         }
335         return delta;
336     }
337
338     /**
339      * @param delta
340      * @param affectedIdVers
341      */

342     private void adjustExternalVisibility(FeatureModelDelta delta,
343             Set JavaDoc affectedIdVers) {
344         if (affectedIdVers != null) {
345             for (Iterator JavaDoc it = affectedIdVers.iterator(); it.hasNext();) {
346                 FeatureTable.Idver idver = (FeatureTable.Idver) it.next();
347                 IFeatureModel[] affectedModels = fActiveModels.get(idver);
348                 if (affectedModels.length > 1) {
349                     /*
350                      * there must have been at least one workspace and one
351                      * external model
352                      */

353                     for (int j = 0; j < affectedModels.length; j++) {
354                         if (affectedModels[j].getUnderlyingResource() == null) {
355                             // move external to inactive
356
fActiveModels.remove(affectedModels[j]);
357                             fInactiveModels.add(affectedModels[j]);
358                             delta.add(affectedModels[j],
359                                     IFeatureModelDelta.REMOVED);
360                         }
361                     }
362                 }
363
364                 if (affectedModels.length <= 0) {
365                     // no workspace model
366
IFeatureModel[] models = fInactiveModels.get(idver);
367                     if (models.length > 0) {
368                         // external model exists, move it to active
369
fInactiveModels.remove(models[0]);
370                         fActiveModels.add(models[0]);
371                         delta.add(models[0], IFeatureModelDelta.ADDED);
372                     }
373                 }
374             }
375         }
376     }
377
378     public void addFeatureModelListener(IFeatureModelListener listener) {
379         if (!fListeners.contains(listener))
380             fListeners.add(listener);
381     }
382
383     public void removeFeatureModelListener(IFeatureModelListener listener) {
384         if (fListeners.contains(listener))
385             fListeners.remove(listener);
386     }
387
388     public void targetReloaded() {
389         fReloadExternalNeeded = true;
390     }
391     
392     public IFeatureModel getDeltaPackFeature() {
393         IFeatureModel model = findFeatureModel("org.eclipse.equinox.executable"); //$NON-NLS-1$
394
if (model == null)
395             model = findFeatureModel("org.eclipse.platform.launchers"); //$NON-NLS-1$
396
return model;
397     }
398
399 }
400
Popular Tags