KickJava   Java API By Example, From Geeks To Geeks.

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


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.Collections JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.ListIterator JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.TreeMap JavaDoc;
20
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.NullProgressMonitor;
25 import org.eclipse.jdt.core.IClasspathContainer;
26 import org.eclipse.jdt.core.IJavaProject;
27 import org.eclipse.jdt.core.JavaCore;
28 import org.eclipse.jdt.core.JavaModelException;
29 import org.eclipse.osgi.service.resolver.BundleDelta;
30 import org.eclipse.osgi.service.resolver.BundleDescription;
31 import org.eclipse.osgi.service.resolver.HostSpecification;
32 import org.eclipse.osgi.service.resolver.StateDelta;
33 import org.eclipse.pde.core.IModel;
34 import org.eclipse.pde.core.IModelProviderEvent;
35 import org.eclipse.pde.core.IModelProviderListener;
36 import org.eclipse.pde.core.build.IBuild;
37 import org.eclipse.pde.core.build.IBuildEntry;
38 import org.eclipse.pde.core.plugin.IPluginModel;
39 import org.eclipse.pde.core.plugin.IPluginModelBase;
40 import org.eclipse.pde.core.plugin.ModelEntry;
41
42 public class PluginModelManager implements IModelProviderListener {
43     
44     /**
45      * Subclass of ModelEntry
46      * It adds methods that add/remove model from the entry.
47      * These methods must not be on ModelEntry itself because
48      * ModelEntry is an API class and we do not want clients to manipulate
49      * the ModelEntry
50      *
51      */

52     private class LocalModelEntry extends ModelEntry {
53         
54         /**
55          * Constructs a model entry that will keep track
56          * of all bundles in the workspace and target that share the same ID.
57          *
58          * @param id the bundle ID
59          */

60         public LocalModelEntry(String JavaDoc id) {
61             super(id);
62         }
63         
64         /**
65          * Adds a model to the entry.
66          * An entry keeps two lists: one for workspace models
67          * and one for target (external) models.
68          * If the model being added is associated with a workspace resource,
69          * it is added to the workspace list; otherwise, it is added to the external list.
70          *
71          * @param model model to be added to the entry
72          */

73         public void addModel(IPluginModelBase model) {
74             if (model.getUnderlyingResource() != null)
75                 fWorkspaceEntries.add(model);
76             else
77                 fExternalEntries.add(model);
78         }
79
80         /**
81          * Removes the given model for the workspace list if the model is associated
82          * with workspace resource. Otherwise, it is removed from the external list.
83          *
84          * @param model model to be removed from the model entry
85          */

86         public void removeModel(IPluginModelBase model) {
87             if (model.getUnderlyingResource() != null)
88                 fWorkspaceEntries.remove(model);
89             else
90                 fExternalEntries.remove(model);
91         }
92     }
93
94     private ExternalModelManager fExternalManager; // keeps track of changes in target models
95
private WorkspacePluginModelManager fWorkspaceManager; // keeps track of changes in the workspace
96
private PDEState fState; // keeps the combined view of the target and workspace
97

98     private Map JavaDoc fEntries; // a master table keyed by plugin ID and the value is a ModelEntry
99
private ArrayList JavaDoc fListeners; // a list of listeners interested in changes to the plug-in models
100
private ArrayList JavaDoc fStateListeners; // a list of listeners interested in changes to the PDE/resolver State
101

102     /**
103      * Initialize the workspace and external (target) model manager
104      * and add listeners to each one
105      */

106     public PluginModelManager() {
107         fWorkspaceManager = new WorkspacePluginModelManager();
108         fExternalManager = new ExternalModelManager();
109         fExternalManager.addModelProviderListener(this);
110         fWorkspaceManager.addModelProviderListener(this);
111     }
112         
113     /**
114      * React to changes in plug-ins in the workspace and/or target
115      */

116     public void modelsChanged(IModelProviderEvent e) {
117         PluginModelDelta delta = new PluginModelDelta();
118         
119         // Removes from the master table and the state all workspace plug-ins that have been
120
// removed (project closed/deleted) from the workspace.
121
// Also if the taget location changes, all models from the old target are removed
122
if ((e.getEventTypes() & IModelProviderEvent.MODELS_REMOVED) != 0) {
123             IModel[] removed = e.getRemovedModels();
124             for (int i = 0; i < removed.length; i++) {
125                 IPluginModelBase model = (IPluginModelBase) removed[i];
126                 String JavaDoc id = model.getPluginBase().getId();
127                 if (id != null)
128                     handleRemove(id, model, delta);
129             }
130         }
131         
132         // reset the state
133
if ((e.getEventTypes() & IModelProviderEvent.TARGET_CHANGED) != 0) {
134             Object JavaDoc newState = e.getEventSource();
135             if (newState instanceof PDEState) {
136                 fState = (PDEState)newState;
137             }
138         }
139         
140         // Adds to the master table and the state newly created plug-ins in the workspace
141
// (ie. new plug-in project or a closed project that has just been re-opened).
142
// Also, if the target location changes, we add all plug-ins from the new target
143
if ((e.getEventTypes() & IModelProviderEvent.MODELS_ADDED) != 0) {
144             IModel[] added = e.getAddedModels();
145             for (int i = 0; i < added.length; i++) {
146                 IPluginModelBase model = (IPluginModelBase) added[i];
147                 String JavaDoc id = model.getPluginBase().getId();
148                 if (id != null)
149                     handleAdd(id, model, delta);
150             }
151         }
152         
153         // add workspace plug-ins to the new state
154
// and remove their target counterparts from the state.
155
if ((e.getEventTypes() & IModelProviderEvent.TARGET_CHANGED) != 0) {
156             IPluginModelBase[] models = fWorkspaceManager.getPluginModels();
157             for (int i = 0; i < models.length; i++) {
158                 addWorkspaceBundleToState(models[i]);
159             }
160             if (models.length > 0)
161                 fState.resolveState(true);
162         }
163         
164         // Update the bundle description of plug-ins whose state has changed.
165
// A plug-in changes state if the MANIFEST.MF has been touched.
166
// or if a plug-in on the Target Platform has changed state (from checked to unchecked,
167
// and vice versa.
168
if ((e.getEventTypes() & IModelProviderEvent.MODELS_CHANGED) != 0) {
169             IModel[] changed = e.getChangedModels();
170             for (int i = 0; i < changed.length; i++)
171                 handleChange((IPluginModelBase)changed[i], delta);
172         }
173         
174         if (fState != null) {
175             // if the target location has not changed, incrementally re-resolve the state after processing all the add/remove/modify changes
176
// Otherwise, the state is in a good resolved state
177
StateDelta stateDelta = (e.getEventTypes() & IModelProviderEvent.TARGET_CHANGED) != 0
178                                     ? null
179                                     : fState.resolveState((e.getEventTypes() & ICoreConstants.ENVIRONMENT_CHANGED) != 0 ? false : true);
180             // trigger a classpath update for all workspace plug-ins affected by the
181
// processed batch of changes
182
updateAffectedEntries(stateDelta);
183             fireStateDelta(stateDelta);
184             
185         }
186         
187         // notify all interested listeners in the changes made to the master table of entries
188
fireDelta(delta);
189     }
190     
191     /**
192      * Trigger a classpath update for all workspace plug-ins affected by the processed
193      * model changes
194      *
195      * @param delta a state delta containing a list of bundles affected by the processed
196      * changes
197      */

198     private void updateAffectedEntries(StateDelta delta) {
199         Map JavaDoc map = new HashMap JavaDoc();
200         if (delta == null) {
201             // if the delta is null, then the entire target changed.
202
// Therefore, we should update the classpath for all workspace plug-ins.
203
IPluginModelBase[] models = getWorkspaceModels();
204             for (int i = 0; i < models.length; i++) {
205                 IProject project = models[i].getUnderlyingResource().getProject();
206                 try {
207                     if (project.hasNature(JavaCore.NATURE_ID)) {
208                         map.put(JavaCore.create(project),
209                                 new RequiredPluginsClasspathContainer(models[i]));
210                     }
211                 } catch (CoreException e) {
212                 }
213             }
214         } else {
215             BundleDelta[] deltas = delta.getChanges();
216             for (int i = 0; i < deltas.length; i++) {
217                 try {
218                     // update classpath for workspace plug-ins that are housed in a
219
// Java project hand have been affected by the processd model changes.
220
IPluginModelBase model = findModel(deltas[i].getBundle());
221                     IResource resource = model == null ? null : model.getUnderlyingResource();
222                     if (resource != null) {
223                         IProject project = resource.getProject();
224                         if (project.hasNature(JavaCore.NATURE_ID)) {
225                             IJavaProject jProject = JavaCore.create(project);
226                             if (!map.containsKey(jProject)) {
227                                 map.put(jProject, new RequiredPluginsClasspathContainer(model));
228                             }
229                         }
230                     }
231                 } catch (CoreException e) {
232                 }
233             }
234             // do secondary dependencies
235
IPluginModelBase[] models = getWorkspaceModels();
236             for (int i = 0; i < models.length; i++) {
237                 IProject project = models[i].getUnderlyingResource().getProject();
238                 try {
239                     if (!project.hasNature(JavaCore.NATURE_ID))
240                         continue;
241                     IJavaProject jProject = JavaCore.create(project);
242                     if (map.containsKey(jProject))
243                         continue;
244                     IBuild build = ClasspathUtilCore.getBuild(models[i]);
245                     if (build != null && build.getEntry(IBuildEntry.SECONDARY_DEPENDENCIES) != null) {
246                         map.put(jProject,
247                                 new RequiredPluginsClasspathContainer(models[i], build));
248                     }
249                 } catch (CoreException e) {
250                 }
251             }
252         }
253         
254         if (map.size() > 0) {
255             try {
256                 // update classpath for all affected workspace plug-ins in one operation
257
IJavaProject[] jProjects = (IJavaProject[])map.keySet().toArray(new IJavaProject[map.size()]);
258                 IClasspathContainer[] containers = (IClasspathContainer[])map.values().toArray(new IClasspathContainer[map.size()]);
259                 JavaCore.setClasspathContainer(
260                     PDECore.REQUIRED_PLUGINS_CONTAINER_PATH, jProjects, containers, null);
261             } catch (JavaModelException e) {
262             }
263         }
264     }
265     
266     /**
267      * Notify all interested listeners in changes made to the master table
268      *
269      * @param delta the delta of changes
270      */

271     private void fireDelta(PluginModelDelta delta) {
272         if (fListeners != null) {
273             for (int i = 0; i < fListeners.size(); i++) {
274                 ((IPluginModelListener)fListeners.get(i)).modelsChanged(delta);
275             }
276         }
277     }
278     
279     /**
280      * Notify all interested listeners in changes made to the resolver State
281      *
282      * @param delta the delta from the resolver State.
283      */

284     private void fireStateDelta(StateDelta delta) {
285         if (fStateListeners != null) {
286             ListIterator JavaDoc li = fStateListeners.listIterator();
287             while (li.hasNext())
288                 ((IStateDeltaListener)li.next()).stateResolved(delta);
289         }
290     }
291     
292     /**
293      * Notify all interested listeners the cached PDEState has changed
294      *
295      * @param newState the new PDEState.
296      */

297     private void fireStateChanged(PDEState newState) {
298         if (fStateListeners != null) {
299             ListIterator JavaDoc li = fStateListeners.listIterator();
300             while (li.hasNext())
301                 ((IStateDeltaListener)li.next()).stateChanged(newState.getState());
302         }
303     }
304
305     /**
306      * Add a listener to the model manager
307      *
308      * @param listener the listener to be added
309      */

310     public void addPluginModelListener(IPluginModelListener listener) {
311         if (fListeners == null)
312             fListeners = new ArrayList JavaDoc();
313         if (!fListeners.contains(listener))
314             fListeners.add(listener);
315     }
316     
317     /**
318      * Add a StateDelta listener to model manager
319      *
320      * @param listener the listener to be added
321      */

322     public void addStateDeltaListener(IStateDeltaListener listener) {
323         if (fStateListeners == null)
324             fStateListeners = new ArrayList JavaDoc();
325         if (!fStateListeners.contains(listener))
326             fStateListeners.add(listener);
327     }
328     
329     /**
330      * Remove a listener from the model manager
331      *
332      * @param listener the listener to be removed
333      */

334     public void removePluginModelListener(IPluginModelListener listener) {
335         if (fListeners != null)
336             fListeners.remove(listener);
337     }
338     
339     /**
340      * Remove a StateDelta listener from the model manager
341      *
342      * @param listener the listener to be removed
343      */

344     public void removeStateDeltaListener(IStateDeltaListener listener) {
345         if (fStateListeners != null)
346             fStateListeners.remove(listener);
347     }
348     
349     /**
350      * Returns <code>true</code> if neither the workspace nor target contains plug-ins;
351      * <code>false</code> otherwise.
352      *
353      * @return <code>true</code> if neither the workspace nor target contains plug-ins;
354      * <code>false</code> otherwise.
355      */

356     public boolean isEmpty() {
357         return getEntryTable().size() == 0;
358     }
359     
360     /**
361      * Returns <code>true</code> if the master table has been initialized;
362      * <code>false</code> otherwise.
363      *
364      * @return <code>true</code> if the master table has been initialized;
365      * <code>false</code> otherwise.
366      */

367     public boolean isInitialized() {
368         return fEntries != null;
369     }
370     
371     /**
372      * Allow access to the table only through this getter.
373      * It always calls initialize to make sure the table is initialized.
374      * If more than one thread tries to read the table at the same time,
375      * and the table is not initialized yet, thread2 would wait.
376      * This way there are no partial reads.
377      */

378     private Map JavaDoc getEntryTable() {
379         initializeTable();
380         return fEntries;
381     }
382
383     /**
384      * This method must be synchronized so that only one thread
385      * initializes the table, and the rest would block until
386      * the table is initialized.
387      *
388      */

389     private synchronized void initializeTable() {
390         if (fEntries != null) return;
391         fEntries = Collections.synchronizedMap(new TreeMap JavaDoc());
392         
393         // Create a state that contains all bundles from the target and workspace
394
// If a workspace bundle has the same symbolic name as a target bundle,
395
// the target counterpart is subsequently removed from the state.
396
fState = new PDEState(
397                         fWorkspaceManager.getPluginPaths(),
398                         fExternalManager.getPluginPaths(),
399                         true,
400                         new NullProgressMonitor());
401         
402         // initialize the enabled/disabled state of target models
403
// based on whether the bundle is checked/unchecked on the Target Platform
404
// preference page.
405
fExternalManager.initializeModels(fState.getTargetModels());
406         
407         // add target models to the master table
408
boolean statechanged = addToTable(fExternalManager.getAllModels());
409         
410         // a state is combined only if the workspace plug-ins have not changed
411
// since the last shutdown of the workbench
412
if (fState.isCombined()) {
413             IPluginModelBase[] models = fState.getWorkspaceModels();
414             // initialize the workspace models from the cached state
415
fWorkspaceManager.initializeModels(models);
416             // add workspace models to the master table
417
addToTable(models);
418             // resolve the state incrementally if some target models
419
// were removed
420
if (statechanged)
421                 fState.resolveState(true);
422         } else {
423             // if we have no good cached state of workspace plug-ins,
424
// re-parse all/any workspace plug-ins
425
IPluginModelBase[] models = fWorkspaceManager.getPluginModels();
426             
427             // add workspace plug-ins to the master table
428
addToTable(models);
429             
430             // add workspace plug-ins to the state
431
// and remove their target counterparts from the state.
432
for (int i = 0; i < models.length; i++) {
433                 addWorkspaceBundleToState(models[i]);
434             }
435             
436             // resolve the state incrementally if any workspace plug-ins were found
437
if (models.length > 0)
438                 fState.resolveState(true);
439         }
440     }
441     
442     /**
443      * Adds the given models to the corresponding ModelEntry in the master table
444      *
445      * @param models the models to be added to the master tabl
446      *
447      * @return <code>true</code> if changes were made to the state; <code>false</code> otherwise
448      */

449     private boolean addToTable(IPluginModelBase[] models) {
450         boolean stateChanged = false;
451         for (int i = 0; i < models.length; i++) {
452             String JavaDoc id = models[i].getPluginBase().getId();
453             if (id == null)
454                 continue;
455             LocalModelEntry entry = (LocalModelEntry)fEntries.get(id);
456             // create a new entry for the given ID if none already exists
457
if (entry == null) {
458                 entry = new LocalModelEntry(id);
459                 fEntries.put(id, entry);
460             }
461             // add the model to the entry
462
entry.addModel(models[i]);
463             
464             // if the model is a disabled external (target) model, remove it from
465
// the state and set the stateChanged flag to true
466
if (models[i].getUnderlyingResource() == null && !models[i].isEnabled()) {
467                 fState.removeBundleDescription(models[i].getBundleDescription());
468                 stateChanged = true;
469             }
470         }
471         return stateChanged;
472     }
473     
474     /**
475      * Add a workspace bundle to the state
476      *
477      * @param model the workspace model
478      */

479     private synchronized void addWorkspaceBundleToState(IPluginModelBase model) {
480         String JavaDoc id = model.getPluginBase().getId();
481         if (id == null)
482             return;
483
484         // remove target models by the same ID from the state, if any
485
ModelEntry entry = (ModelEntry)fEntries.get(id);
486         if (entry != null) {
487             IPluginModelBase[] models = entry.getExternalModels();
488             for (int i = 0; i < models.length; i++)
489                 fState.removeBundleDescription(models[i].getBundleDescription());
490         }
491         
492         // add new bundle to the state
493
fState.addBundle(model, false);
494         
495         BundleDescription desc = model.getBundleDescription();
496         if (desc != null) {
497             // refresh host if a fragment is added to the state.
498
// this is necessary because the state will not re-resolve dynamically added fragments
499
// on its own
500
HostSpecification spec = desc.getHost();
501             if (spec != null
502                 && ("true".equals(System.getProperty("pde.allowCycles")) //$NON-NLS-1$ //$NON-NLS-2$
503
|| ClasspathUtilCore.isPatchFragment(desc)
504                     || desc.getImportPackages().length > 0
505                     || desc.getRequiredBundles().length > 0)) {
506                 BundleDescription host = (BundleDescription)spec.getSupplier();
507                 if (host != null) {
508                     ModelEntry hostEntry = (ModelEntry)fEntries.get(host.getName());
509                     if (hostEntry != null) {
510                         fState.addBundle(hostEntry.getModel(host), true);
511                     }
512                 }
513             }
514         }
515     }
516     
517     /**
518      * Adds a model to the master table and state
519      *
520      * @param id the key
521      * @param model the model being added
522      */

523     private void handleAdd(String JavaDoc id, IPluginModelBase model, PluginModelDelta delta) {
524         LocalModelEntry entry = (LocalModelEntry)getEntryTable().get(id);
525         
526         // add model to the corresponding ModelEntry. Create a new entry if necessary
527
if (entry == null) {
528             entry = new LocalModelEntry(id);
529             getEntryTable().put(id, entry);
530             delta.addEntry(entry, PluginModelDelta.ADDED);
531         } else {
532             delta.addEntry(entry, PluginModelDelta.CHANGED);
533         }
534         entry.addModel(model);
535         
536         // if the model added is a workspace model, add it to the state and
537
// remove all its external counterparts
538
if (model.getUnderlyingResource() != null) {
539             addWorkspaceBundleToState(model);
540         } else if (model.isEnabled() && !entry.hasWorkspaceModels()) {
541             // if a target model has went from an unchecked state to a checked state
542
// on the target platform preference page, re-add its bundle description
543
// to the state
544
BundleDescription desc = model.getBundleDescription();
545             if (desc.getContainingState().equals(fState))
546                 fState.addBundleDescription(desc);
547         }
548     }
549     
550     /**
551      * Removes the model from the ModelEntry and the state. The entire model entry is removed
552      * once the last model it retains is removed.
553      *
554      * @param id the key
555      * @param model the model to be removed
556      */

557     private void handleRemove(String JavaDoc id, IPluginModelBase model, PluginModelDelta delta) {
558         LocalModelEntry entry = (LocalModelEntry)getEntryTable().get(id);
559         if (entry != null) {
560             // remove model from the entry
561
entry.removeModel(model);
562             // remove corresponding bundle description from the state
563
fState.removeBundleDescription(model.getBundleDescription());
564             if (!entry.hasExternalModels() && !entry.hasWorkspaceModels()) {
565                 // remove entire entry if it has no models left
566
getEntryTable().remove(id);
567                 delta.addEntry(entry, PluginModelDelta.REMOVED);
568                 return;
569             } else if (model.getUnderlyingResource() != null && !entry.hasWorkspaceModels()){
570                 // re-add enabled external counterparts to the state, if the last workspace
571
// plug-in with a particular symbolic name is removed
572
IPluginModelBase[] external = entry.getExternalModels();
573                 for (int i = 0; i < external.length; i++) {
574                     if (external[i].isEnabled())
575                         fState.addBundleDescription(external[i].getBundleDescription());
576                 }
577             }
578             delta.addEntry(entry, PluginModelDelta.CHANGED);
579         }
580     }
581     
582     /**
583      * Update the state and master table to account for the change in the given model
584      *
585      * @param model the model that has changed
586      */

587     private void handleChange(IPluginModelBase model, PluginModelDelta delta) {
588         BundleDescription desc = model.getBundleDescription();
589         String JavaDoc oldID = desc == null ? null : desc.getSymbolicName();
590         String JavaDoc newID = model.getPluginBase().getId();
591         
592         // if the model still has no symbolic name (ie. a MANIFEST.MF without the
593
// Bundle-SymbolicName header), keep ignoring it
594
if (oldID == null && newID == null)
595             return;
596         
597         // if the model used to lack a Bundle-SymbolicName header and now it has one,
598
// treat it as a regular model addition
599
if (oldID == null && newID != null) {
600             handleAdd(newID, model, delta);
601         } else if (oldID != null && newID == null) {
602             // if the model used to have a Bundle-SymbolicName header and now it lost it,
603
// treat it as a regular model removal
604
handleRemove(oldID, model, delta);
605             model.setBundleDescription(null);
606         } else if (oldID.equals(newID)) {
607             // if the workspace bundle's MANIFEST.MF was touched or
608
// if the a target plug-in has now become enabled/checked, update the model
609
// in the state
610
if (model.isEnabled())
611                 fState.addBundle(model, true);
612             else
613                 // if the target plug-in has become disabled/unchecked, remove its bundle
614
// description from the state
615
fState.removeBundleDescription(model.getBundleDescription());
616             delta.addEntry(findEntry(oldID), PluginModelDelta.CHANGED);
617         } else {
618             // if the symbolic name of the bundle has completely changed,
619
// remove the model from the old entry, and add the model to the new entry
620
handleRemove(oldID, model, delta);
621             handleAdd(newID, model, delta);
622         }
623     }
624         
625     /**
626      * Returns a model entry containing all workspace and target plug-ins by the given ID
627      *
628      * @param id the plug-in ID
629      *
630      * @return a model entry containing all workspace and target plug-ins by the given ID
631      */

632     public ModelEntry findEntry(String JavaDoc id) {
633         if ("system.bundle".equals(id)) //$NON-NLS-1$
634
id = "org.eclipse.osgi"; //$NON-NLS-1$
635
return id == null ? null : (ModelEntry)getEntryTable().get(id);
636     }
637
638     /**
639      * Returns the plug-in model for the best match plug-in with the given ID.
640      * A null value is returned if no such bundle is found in the workspace or target platform.
641      * <p>
642      * A workspace plug-in is always preferably returned over a target plug-in.
643      * A plug-in that is checked/enabled on the Target Platform preference page is always
644      * preferably returned over a target plug-in that is unchecked/disabled.
645      * </p>
646      * <p>
647      * In the case of a tie among workspace plug-ins or among target plug-ins,
648      * the plug-in with the highest version is returned.
649      * </p>
650      * <p>
651      * In the case of a tie among more than one suitable plug-in that have the same version,
652      * one of those plug-ins is randomly returned.
653      * </p>
654      *
655      * @param id the plug-in ID
656      * @return the plug-in model for the best match plug-in with the given ID
657      */

658     public IPluginModelBase findModel(String JavaDoc id) {
659         ModelEntry entry = findEntry(id);
660         return entry == null ? null : entry.getModel();
661     }
662     
663     /**
664      * Returns the plug-in model corresponding to the given project, or <code>null</code>
665      * if the project does not represent a plug-in project or if it contains a manifest file
666      * that is malformed or missing vital information.
667      *
668      * @param project the project
669      * @return a plug-in model corresponding to the project or <code>null</code> if the project
670      * is not a plug-in project
671      */

672     public IPluginModelBase findModel(IProject project) {
673         initializeTable();
674         return fWorkspaceManager.getPluginModel(project);
675     }
676     
677     /**
678      * Returns a plug-in model associated with the given bundle description
679      *
680      * @param desc the bundle description
681      *
682      * @return a plug-in model associated with the given bundle description or <code>null</code>
683      * if none exists
684      */

685     public IPluginModelBase findModel(BundleDescription desc) {
686         ModelEntry entry = findEntry(desc.getSymbolicName());
687         return entry == null ? null : entry.getModel(desc);
688     }
689     
690     /**
691      * Returns all plug-ins and fragments in the workspace as well as all plug-ins and fragments that are
692      * checked on the Target Platform preference page.
693      * <p>
694      * If a workspace plug-in/fragment has the same ID as a target plug-in/fragment, the target counterpart
695      * is skipped and not included.
696      * </p>
697      * <p>
698      * Equivalent to <code>getActiveModels(true)</code>
699      * </p>
700      *
701      * @return all plug-ins and fragments in the workspace as well as all plug-ins and fragments that are
702      * checked on the Target Platform preference page.
703      */

704     public IPluginModelBase[] getActiveModels() {
705         return getActiveModels(true);
706     }
707
708     /**
709      * Returns all plug-ins and (possibly) fragments in the workspace as well as all plug-ins and (possibly)
710      * fragments that are checked on the Target Platform preference page.
711      * <p>
712      * If a workspace plug-in/fragment has the same ID as a target plug-in, the target counterpart
713      * is skipped and not included.
714      * </p>
715      * <p>
716      * The returned result includes fragments only if <code>includeFragments</code>
717      * is set to true
718      * </p>
719      * @param includeFragments a boolean indicating if fragments are desired in the returned
720      * result
721      * @return all plug-ins and (possibly) fragments in the workspace as well as all plug-ins and
722      * (possibly) fragments that are checked on the Target Platform preference page.
723      */

724     public IPluginModelBase[] getActiveModels(boolean includeFragments) {
725         int size = getEntryTable().size();
726         ArrayList JavaDoc result = new ArrayList JavaDoc(size);
727         Iterator JavaDoc iter = getEntryTable().values().iterator();
728         while (iter.hasNext()) {
729             ModelEntry entry = (ModelEntry)iter.next();
730             IPluginModelBase[] models = entry.getActiveModels();
731             for (int i = 0; i < models.length; i++) {
732                 if (models[i] instanceof IPluginModel || includeFragments)
733                     result.add(models[i]);
734             }
735         }
736         return (IPluginModelBase[])result.toArray(new IPluginModelBase[result.size()]);
737     }
738
739     /**
740      * Returns all plug-ins and fragments in the workspace as well as all target plug-ins and fragments, regardless
741      * whether or not they are checked or not on the Target Platform preference page.
742      * <p>
743      * If a workspace plug-in/fragment has the same ID as a target plug-in, the target counterpart
744      * is skipped and not included.
745      * </p>
746      * <p>
747      * Equivalent to <code>getAllModels(true)</code>
748      * </p>
749      *
750      * @return all plug-ins and fragments in the workspace as well as all target plug-ins and fragments, regardless
751      * whether or not they are checked on the Target Platform preference page.
752      */

753     public IPluginModelBase[] getAllModels() {
754         return getAllModels(true);
755     }
756     
757     /**
758      * Returns all plug-ins and (possibly) fragments in the workspace as well as all plug-ins
759      * and (possibly) fragments, regardless whether or not they are
760      * checked on the Target Platform preference page.
761      * <p>
762      * If a workspace plug-in/fragment has the same ID as a target plug-in/fragment, the target counterpart
763      * is skipped and not included.
764      * </p>
765      * <p>
766      * The returned result includes fragments only if <code>includeFragments</code>
767      * is set to true
768      * </p>
769      * @param includeFragments a boolean indicating if fragments are desired in the returned
770      * result
771      * @return ll plug-ins and (possibly) fragments in the workspace as well as all plug-ins
772      * and (possibly) fragments, regardless whether or not they are
773      * checked on the Target Platform preference page.
774      */

775     public IPluginModelBase[] getAllModels(boolean includeFragments) {
776         int size = getEntryTable().size();
777         ArrayList JavaDoc result = new ArrayList JavaDoc(size);
778         Iterator JavaDoc iter = getEntryTable().values().iterator();
779         while (iter.hasNext()) {
780             ModelEntry entry = (ModelEntry)iter.next();
781             IPluginModelBase[] models = entry.hasWorkspaceModels()
782                                             ? entry.getWorkspaceModels()
783                                             : entry.getExternalModels();
784             for (int i = 0; i < models.length; i++) {
785                 if (models[i] instanceof IPluginModel || includeFragments)
786                     result.add(models[i]);
787             }
788         }
789         return (IPluginModelBase[])result.toArray(new IPluginModelBase[result.size()]);
790     }
791     
792     /**
793      * Returns all plug-in models in the target platform
794      *
795      * @return all plug-ins in the target platform
796      */

797     public IPluginModelBase[] getExternalModels() {
798         initializeTable();
799         return fExternalManager.getAllModels();
800     }
801     
802     /**
803      * Returns all plug-in models in the workspace
804      *
805      * @return all plug-in models in the workspace
806      */

807     public IPluginModelBase[] getWorkspaceModels() {
808         initializeTable();
809         return fWorkspaceManager.getPluginModels();
810     }
811     
812     /**
813      * Return the model manager that keeps track of plug-ins in the target platform
814      *
815      * @return the model manager that keeps track of plug-ins in the target platform
816      */

817     public ExternalModelManager getExternalModelManager() {
818         initializeTable();
819         return fExternalManager;
820     }
821
822     /**
823      * Returns the state containing bundle descriptions for workspace plug-ins and target plug-ins
824      * that form the current PDE state
825      * @return
826      */

827     public PDEState getState() {
828         initializeTable();
829         return fState;
830     }
831     
832     /**
833      * Sets the PDE state. This method is meant to be called when the target platform
834      * location changes.
835      *
836      * @param state the new state
837      */

838     public void resetState(PDEState state) {
839         if (fState != null && fState.equals(state))
840             return;
841         // clear all models and add new ones
842
int type = IModelProviderEvent.TARGET_CHANGED;
843         IModel[] removed = fState.getTargetModels();
844         if (removed.length > 0)
845             type |= IModelProviderEvent.MODELS_REMOVED;
846         IModel[] added = state.getTargetModels();
847         if (added.length > 0)
848             type |= IModelProviderEvent.MODELS_ADDED;
849         modelsChanged(new ModelProviderEvent(
850                         state,
851                         type,
852                         added,
853                         removed,
854                         new IModel[0]));
855
856         fireStateChanged(state);
857     }
858     
859     /**
860      * Perform cleanup upon shutting down
861      */

862     public void shutdown() {
863         fWorkspaceManager.shutdown();
864         fExternalManager.shutdown();
865         if (fState != null)
866             fState.shutdown();
867         if (fListeners != null)
868             fListeners.clear();
869         if (fStateListeners != null)
870             fStateListeners.clear();
871     }
872
873 }
874
Popular Tags