1 11 package org.eclipse.pde.internal.core; 12 13 import java.util.ArrayList ; 14 import java.util.Collections ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.ListIterator ; 18 import java.util.Map ; 19 import java.util.TreeMap ; 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 52 private class LocalModelEntry extends ModelEntry { 53 54 60 public LocalModelEntry(String id) { 61 super(id); 62 } 63 64 73 public void addModel(IPluginModelBase model) { 74 if (model.getUnderlyingResource() != null) 75 fWorkspaceEntries.add(model); 76 else 77 fExternalEntries.add(model); 78 } 79 80 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; private WorkspacePluginModelManager fWorkspaceManager; private PDEState fState; 98 private Map fEntries; private ArrayList fListeners; private ArrayList fStateListeners; 102 106 public PluginModelManager() { 107 fWorkspaceManager = new WorkspacePluginModelManager(); 108 fExternalManager = new ExternalModelManager(); 109 fExternalManager.addModelProviderListener(this); 110 fWorkspaceManager.addModelProviderListener(this); 111 } 112 113 116 public void modelsChanged(IModelProviderEvent e) { 117 PluginModelDelta delta = new PluginModelDelta(); 118 119 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 id = model.getPluginBase().getId(); 127 if (id != null) 128 handleRemove(id, model, delta); 129 } 130 } 131 132 if ((e.getEventTypes() & IModelProviderEvent.TARGET_CHANGED) != 0) { 134 Object newState = e.getEventSource(); 135 if (newState instanceof PDEState) { 136 fState = (PDEState)newState; 137 } 138 } 139 140 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 id = model.getPluginBase().getId(); 148 if (id != null) 149 handleAdd(id, model, delta); 150 } 151 } 152 153 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 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 StateDelta stateDelta = (e.getEventTypes() & IModelProviderEvent.TARGET_CHANGED) != 0 178 ? null 179 : fState.resolveState((e.getEventTypes() & ICoreConstants.ENVIRONMENT_CHANGED) != 0 ? false : true); 180 updateAffectedEntries(stateDelta); 183 fireStateDelta(stateDelta); 184 185 } 186 187 fireDelta(delta); 189 } 190 191 198 private void updateAffectedEntries(StateDelta delta) { 199 Map map = new HashMap (); 200 if (delta == null) { 201 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 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 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 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 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 284 private void fireStateDelta(StateDelta delta) { 285 if (fStateListeners != null) { 286 ListIterator li = fStateListeners.listIterator(); 287 while (li.hasNext()) 288 ((IStateDeltaListener)li.next()).stateResolved(delta); 289 } 290 } 291 292 297 private void fireStateChanged(PDEState newState) { 298 if (fStateListeners != null) { 299 ListIterator li = fStateListeners.listIterator(); 300 while (li.hasNext()) 301 ((IStateDeltaListener)li.next()).stateChanged(newState.getState()); 302 } 303 } 304 305 310 public void addPluginModelListener(IPluginModelListener listener) { 311 if (fListeners == null) 312 fListeners = new ArrayList (); 313 if (!fListeners.contains(listener)) 314 fListeners.add(listener); 315 } 316 317 322 public void addStateDeltaListener(IStateDeltaListener listener) { 323 if (fStateListeners == null) 324 fStateListeners = new ArrayList (); 325 if (!fStateListeners.contains(listener)) 326 fStateListeners.add(listener); 327 } 328 329 334 public void removePluginModelListener(IPluginModelListener listener) { 335 if (fListeners != null) 336 fListeners.remove(listener); 337 } 338 339 344 public void removeStateDeltaListener(IStateDeltaListener listener) { 345 if (fStateListeners != null) 346 fStateListeners.remove(listener); 347 } 348 349 356 public boolean isEmpty() { 357 return getEntryTable().size() == 0; 358 } 359 360 367 public boolean isInitialized() { 368 return fEntries != null; 369 } 370 371 378 private Map getEntryTable() { 379 initializeTable(); 380 return fEntries; 381 } 382 383 389 private synchronized void initializeTable() { 390 if (fEntries != null) return; 391 fEntries = Collections.synchronizedMap(new TreeMap ()); 392 393 fState = new PDEState( 397 fWorkspaceManager.getPluginPaths(), 398 fExternalManager.getPluginPaths(), 399 true, 400 new NullProgressMonitor()); 401 402 fExternalManager.initializeModels(fState.getTargetModels()); 406 407 boolean statechanged = addToTable(fExternalManager.getAllModels()); 409 410 if (fState.isCombined()) { 413 IPluginModelBase[] models = fState.getWorkspaceModels(); 414 fWorkspaceManager.initializeModels(models); 416 addToTable(models); 418 if (statechanged) 421 fState.resolveState(true); 422 } else { 423 IPluginModelBase[] models = fWorkspaceManager.getPluginModels(); 426 427 addToTable(models); 429 430 for (int i = 0; i < models.length; i++) { 433 addWorkspaceBundleToState(models[i]); 434 } 435 436 if (models.length > 0) 438 fState.resolveState(true); 439 } 440 } 441 442 449 private boolean addToTable(IPluginModelBase[] models) { 450 boolean stateChanged = false; 451 for (int i = 0; i < models.length; i++) { 452 String id = models[i].getPluginBase().getId(); 453 if (id == null) 454 continue; 455 LocalModelEntry entry = (LocalModelEntry)fEntries.get(id); 456 if (entry == null) { 458 entry = new LocalModelEntry(id); 459 fEntries.put(id, entry); 460 } 461 entry.addModel(models[i]); 463 464 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 479 private synchronized void addWorkspaceBundleToState(IPluginModelBase model) { 480 String id = model.getPluginBase().getId(); 481 if (id == null) 482 return; 483 484 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 fState.addBundle(model, false); 494 495 BundleDescription desc = model.getBundleDescription(); 496 if (desc != null) { 497 HostSpecification spec = desc.getHost(); 501 if (spec != null 502 && ("true".equals(System.getProperty("pde.allowCycles")) || 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 523 private void handleAdd(String id, IPluginModelBase model, PluginModelDelta delta) { 524 LocalModelEntry entry = (LocalModelEntry)getEntryTable().get(id); 525 526 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 (model.getUnderlyingResource() != null) { 539 addWorkspaceBundleToState(model); 540 } else if (model.isEnabled() && !entry.hasWorkspaceModels()) { 541 BundleDescription desc = model.getBundleDescription(); 545 if (desc.getContainingState().equals(fState)) 546 fState.addBundleDescription(desc); 547 } 548 } 549 550 557 private void handleRemove(String id, IPluginModelBase model, PluginModelDelta delta) { 558 LocalModelEntry entry = (LocalModelEntry)getEntryTable().get(id); 559 if (entry != null) { 560 entry.removeModel(model); 562 fState.removeBundleDescription(model.getBundleDescription()); 564 if (!entry.hasExternalModels() && !entry.hasWorkspaceModels()) { 565 getEntryTable().remove(id); 567 delta.addEntry(entry, PluginModelDelta.REMOVED); 568 return; 569 } else if (model.getUnderlyingResource() != null && !entry.hasWorkspaceModels()){ 570 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 587 private void handleChange(IPluginModelBase model, PluginModelDelta delta) { 588 BundleDescription desc = model.getBundleDescription(); 589 String oldID = desc == null ? null : desc.getSymbolicName(); 590 String newID = model.getPluginBase().getId(); 591 592 if (oldID == null && newID == null) 595 return; 596 597 if (oldID == null && newID != null) { 600 handleAdd(newID, model, delta); 601 } else if (oldID != null && newID == null) { 602 handleRemove(oldID, model, delta); 605 model.setBundleDescription(null); 606 } else if (oldID.equals(newID)) { 607 if (model.isEnabled()) 611 fState.addBundle(model, true); 612 else 613 fState.removeBundleDescription(model.getBundleDescription()); 616 delta.addEntry(findEntry(oldID), PluginModelDelta.CHANGED); 617 } else { 618 handleRemove(oldID, model, delta); 621 handleAdd(newID, model, delta); 622 } 623 } 624 625 632 public ModelEntry findEntry(String id) { 633 if ("system.bundle".equals(id)) id = "org.eclipse.osgi"; return id == null ? null : (ModelEntry)getEntryTable().get(id); 636 } 637 638 658 public IPluginModelBase findModel(String id) { 659 ModelEntry entry = findEntry(id); 660 return entry == null ? null : entry.getModel(); 661 } 662 663 672 public IPluginModelBase findModel(IProject project) { 673 initializeTable(); 674 return fWorkspaceManager.getPluginModel(project); 675 } 676 677 685 public IPluginModelBase findModel(BundleDescription desc) { 686 ModelEntry entry = findEntry(desc.getSymbolicName()); 687 return entry == null ? null : entry.getModel(desc); 688 } 689 690 704 public IPluginModelBase[] getActiveModels() { 705 return getActiveModels(true); 706 } 707 708 724 public IPluginModelBase[] getActiveModels(boolean includeFragments) { 725 int size = getEntryTable().size(); 726 ArrayList result = new ArrayList (size); 727 Iterator 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 753 public IPluginModelBase[] getAllModels() { 754 return getAllModels(true); 755 } 756 757 775 public IPluginModelBase[] getAllModels(boolean includeFragments) { 776 int size = getEntryTable().size(); 777 ArrayList result = new ArrayList (size); 778 Iterator 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 797 public IPluginModelBase[] getExternalModels() { 798 initializeTable(); 799 return fExternalManager.getAllModels(); 800 } 801 802 807 public IPluginModelBase[] getWorkspaceModels() { 808 initializeTable(); 809 return fWorkspaceManager.getPluginModels(); 810 } 811 812 817 public ExternalModelManager getExternalModelManager() { 818 initializeTable(); 819 return fExternalManager; 820 } 821 822 827 public PDEState getState() { 828 initializeTable(); 829 return fState; 830 } 831 832 838 public void resetState(PDEState state) { 839 if (fState != null && fState.equals(state)) 840 return; 841 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 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 |