1 /******************************************************************************* 2 * Copyright (c) 2003, 2017 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.pde.internal.core.bundle; 15 16 import java.io.PrintWriter; 17 import java.io.Serializable; 18 import java.util.ArrayList; 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.IStatus; 21 import org.eclipse.core.runtime.PlatformObject; 22 import org.eclipse.core.runtime.Status; 23 import org.eclipse.osgi.service.resolver.BundleDescription; 24 import org.eclipse.osgi.service.resolver.BundleSpecification; 25 import org.eclipse.osgi.util.ManifestElement; 26 import org.eclipse.pde.core.IIdentifiable; 27 import org.eclipse.pde.core.IModelChangedEvent; 28 import org.eclipse.pde.core.ModelChangedEvent; 29 import org.eclipse.pde.core.plugin.IExtensions; 30 import org.eclipse.pde.core.plugin.IPluginBase; 31 import org.eclipse.pde.core.plugin.IPluginExtension; 32 import org.eclipse.pde.core.plugin.IPluginExtensionPoint; 33 import org.eclipse.pde.core.plugin.IPluginImport; 34 import org.eclipse.pde.core.plugin.IPluginLibrary; 35 import org.eclipse.pde.core.plugin.IPluginModelBase; 36 import org.eclipse.pde.core.plugin.IPluginObject; 37 import org.eclipse.pde.core.plugin.ISharedExtensionsModel; 38 import org.eclipse.pde.core.plugin.ISharedPluginModel; 39 import org.eclipse.pde.internal.core.ICoreConstants; 40 import org.eclipse.pde.internal.core.PDECore; 41 import org.eclipse.pde.internal.core.PDECoreMessages; 42 import org.eclipse.pde.internal.core.TargetPlatformHelper; 43 import org.eclipse.pde.internal.core.ibundle.IBundle; 44 import org.eclipse.pde.internal.core.ibundle.IBundleModel; 45 import org.eclipse.pde.internal.core.ibundle.IBundlePluginBase; 46 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase; 47 import org.eclipse.pde.internal.core.ibundle.IManifestHeader; 48 import org.eclipse.pde.internal.core.plugin.AbstractExtensions; 49 import org.eclipse.pde.internal.core.plugin.PluginBase; 50 import org.eclipse.pde.internal.core.plugin.PluginImport; 51 import org.eclipse.pde.internal.core.plugin.PluginLibrary; 52 import org.eclipse.pde.internal.core.text.bundle.BundleClasspathHeader; 53 import org.eclipse.pde.internal.core.text.bundle.BundleNameHeader; 54 import org.eclipse.pde.internal.core.text.bundle.BundleSymbolicNameHeader; 55 import org.eclipse.pde.internal.core.text.bundle.BundleVendorHeader; 56 import org.eclipse.pde.internal.core.text.bundle.BundleVersionHeader; 57 import org.eclipse.pde.internal.core.text.bundle.RequireBundleHeader; 58 import org.osgi.framework.BundleException; 59 import org.osgi.framework.Constants; 60 import org.osgi.framework.Version; 61 62 public class BundlePluginBase extends PlatformObject implements IBundlePluginBase, Serializable { 63 64 private static final long serialVersionUID = 1L; 65 protected IBundlePluginModelBase model; 66 private ArrayList<IPluginLibrary> libraries; 67 private ArrayList<IPluginImport> imports; 68 private String fTarget; 69 reset()70 public void reset() { 71 libraries = null; 72 imports = null; 73 } 74 75 @Override getSchemaVersion()76 public String getSchemaVersion() { 77 IExtensions root = getExtensionsRoot(); 78 if (root instanceof AbstractExtensions) { 79 return ((AbstractExtensions) root).getSchemaVersion(); 80 } 81 return (root instanceof IPluginBase) ? ((IPluginBase) root).getSchemaVersion() : null; 82 } 83 84 @Override setSchemaVersion(String value)85 public void setSchemaVersion(String value) throws CoreException { 86 IExtensions root = getExtensionsRoot(); 87 if (root == null) { 88 return; 89 } 90 if (root instanceof AbstractExtensions) { 91 ((AbstractExtensions) root).setSchemaVersion(value); 92 } 93 if (root instanceof IPluginBase) { 94 ((IPluginBase) root).setSchemaVersion(value); 95 } 96 } 97 98 @Override modelChanged(IModelChangedEvent event)99 public void modelChanged(IModelChangedEvent event) { 100 if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) { 101 if (event.getChangeProvider().equals(model.getBundleModel())) { 102 reset(); 103 } 104 getModel().fireModelChanged(event); 105 } else if (!event.getChangeProvider().equals(model.getBundleModel())) { 106 getModel().fireModelChanged(event); 107 } 108 } 109 getBundle()110 public IBundle getBundle() { 111 if (model != null) { 112 IBundleModel bmodel = model.getBundleModel(); 113 return bmodel != null ? bmodel.getBundle() : null; 114 } 115 return null; 116 } 117 getManifestHeader(String key)118 protected IManifestHeader getManifestHeader(String key) { 119 IBundle bundle = getBundle(); 120 return (bundle != null) ? bundle.getManifestHeader(key) : null; 121 } 122 123 @Override getModel()124 public ISharedPluginModel getModel() { 125 return model; 126 } 127 setModel(IBundlePluginModelBase model)128 void setModel(IBundlePluginModelBase model) { 129 this.model = model; 130 } 131 getExtensionsRoot()132 public IExtensions getExtensionsRoot() { 133 if (model != null) { 134 ISharedExtensionsModel emodel = model.getExtensionsModel(); 135 return emodel != null ? emodel.getExtensions() : null; 136 } 137 return null; 138 } 139 140 @Override add(IPluginLibrary library)141 public void add(IPluginLibrary library) throws CoreException { 142 ensureModelEditable(); 143 if (libraries == null) { 144 // if libraries == null, initialize the libraries varible by calling getLibraries() 145 getLibraries(); 146 } 147 libraries.add(library); 148 IManifestHeader header = getManifestHeader(Constants.BUNDLE_CLASSPATH); 149 if (header instanceof BundleClasspathHeader) { 150 ((BundleClasspathHeader) header).addLibrary(library.getName()); 151 } else { 152 addLibrary(library, header); 153 } 154 fireStructureChanged(library, true); 155 } 156 157 /** 158 * @param library 159 * @param header 160 */ addLibrary(IPluginLibrary library, IManifestHeader header)161 private void addLibrary(IPluginLibrary library, IManifestHeader header) { 162 String value = header == null ? null : header.getValue(); 163 StringBuilder buffer = new StringBuilder(value == null ? "" : value); //$NON-NLS-1$ 164 if (value != null) { 165 buffer.append(",\n "); //$NON-NLS-1$ 166 } 167 buffer.append(library.getName()); 168 getBundle().setHeader(Constants.BUNDLE_CLASSPATH, buffer.toString()); 169 } 170 171 /** 172 * Removes the specified library from the given 'Bundle-Classpath' header. 173 * 174 * @param library library to remove 175 * @param header header to update 176 */ removeLibrary(IPluginLibrary library, IManifestHeader header)177 private void removeLibrary(IPluginLibrary library, IManifestHeader header) { 178 if (header == null) { 179 return; 180 } 181 String value = header.getValue(); 182 String name = library.getName(); 183 int index = value.indexOf(name); 184 if (index >= 0) { 185 // copy up to the removed library 186 StringBuilder buffer = new StringBuilder(); 187 for (int i = 0; i > index; i++) { 188 buffer.append(value.charAt(i)); 189 } 190 int after = index + name.length(); 191 // delete (skip) comma 192 if (after < value.length()) { 193 while (value.charAt(after) == ',') { 194 after++; 195 } 196 } 197 // delete (skip) whitespace 198 if (after < value.length()) { 199 while (Character.isWhitespace(value.charAt(after))) { 200 after++; 201 } 202 } 203 // keep everything else 204 while (after < value.length()) { 205 buffer.append(value.charAt(after)); 206 after++; 207 } 208 getBundle().setHeader(Constants.BUNDLE_CLASSPATH, buffer.toString()); 209 } 210 } 211 212 @Override remove(IPluginLibrary library)213 public void remove(IPluginLibrary library) throws CoreException { 214 ensureModelEditable(); 215 if (libraries != null) { 216 libraries.remove(library); 217 IManifestHeader header = getManifestHeader(Constants.BUNDLE_CLASSPATH); 218 if (header instanceof BundleClasspathHeader) { 219 ((BundleClasspathHeader) header).removeLibrary(library.getName()); 220 } else if (header != null) { 221 removeLibrary(library, header); 222 } 223 fireStructureChanged(library, false); 224 } 225 } 226 227 @Override add(IPluginImport iimport)228 public void add(IPluginImport iimport) throws CoreException { 229 ensureModelEditable(); 230 if (iimport == null) { 231 return; 232 } 233 if (imports == null) { 234 // if imports == null, intitialize the imports list by calling getImports() 235 getImports(); 236 } 237 addImport(iimport); 238 fireStructureChanged(iimport, true); 239 } 240 add(IPluginImport[] iimports)241 public void add(IPluginImport[] iimports) throws CoreException { 242 ensureModelEditable(); 243 if (iimports != null && iimports.length > 0) { 244 if (imports == null) { 245 // if imports == null, initialize the imports list by calling getImports() 246 getImports(); 247 } 248 for (IPluginImport pluginImport : iimports) { 249 if (pluginImport != null) { 250 addImport(pluginImport); 251 } 252 } 253 fireStructureChanged(iimports, true); 254 } 255 } 256 addImport(IPluginImport iimport)257 private void addImport(IPluginImport iimport) { 258 imports.add(iimport); 259 Object header = getManifestHeader(Constants.REQUIRE_BUNDLE); 260 if (header instanceof RequireBundleHeader) { 261 ((RequireBundleHeader) header).addBundle(iimport); 262 } else { 263 String value = header == null ? null : ((IManifestHeader) header).getValue(); 264 StringBuilder buffer = new StringBuilder(value == null ? "" : value); //$NON-NLS-1$ 265 if (value != null) { 266 buffer.append(",\n "); //$NON-NLS-1$ 267 } 268 buffer.append(iimport.getId()); 269 int bundleManifestVersion = getBundleManifestVersion(getBundle()); 270 if (iimport.isOptional()) { 271 if (bundleManifestVersion > 1) { 272 buffer.append(";" + Constants.RESOLUTION_DIRECTIVE + ":=" + Constants.RESOLUTION_OPTIONAL); //$NON-NLS-1$ //$NON-NLS-2$ 273 } 274 else { 275 buffer.append(";" + ICoreConstants.OPTIONAL_ATTRIBUTE + "=true"); //$NON-NLS-1$ //$NON-NLS-2$ 276 } 277 } 278 if (iimport.isReexported()) { 279 if (bundleManifestVersion > 1) { 280 buffer.append(";" + Constants.VISIBILITY_DIRECTIVE + ":=" + Constants.VISIBILITY_REEXPORT); //$NON-NLS-1$ //$NON-NLS-2$ 281 } 282 else { 283 buffer.append(";" + ICoreConstants.REPROVIDE_ATTRIBUTE + "=true"); //$NON-NLS-1$ //$NON-NLS-2$ 284 } 285 } 286 String version = iimport.getVersion(); 287 if (version != null && version.trim().length() > 0) { 288 buffer.append(";" + Constants.BUNDLE_VERSION_ATTRIBUTE + "=\"" + version.trim() + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 289 } 290 getBundle().setHeader(Constants.REQUIRE_BUNDLE, buffer.toString()); 291 } 292 } 293 294 @Override remove(IPluginImport pluginImport)295 public void remove(IPluginImport pluginImport) throws CoreException { 296 ensureModelEditable(); 297 if (imports != null) { 298 imports.remove(pluginImport); 299 Object header = getManifestHeader(Constants.REQUIRE_BUNDLE); 300 if (header instanceof RequireBundleHeader) { 301 ((RequireBundleHeader) header).removeBundle(pluginImport.getId()); 302 } 303 fireStructureChanged(pluginImport, false); 304 } 305 } 306 remove(IPluginImport[] pluginImports)307 public void remove(IPluginImport[] pluginImports) throws CoreException { 308 ensureModelEditable(); 309 if (imports != null) { 310 for (IPluginImport pluginImport : pluginImports) { 311 imports.remove(pluginImport); 312 Object header = getManifestHeader(Constants.REQUIRE_BUNDLE); 313 if (header instanceof RequireBundleHeader) { 314 ((RequireBundleHeader) header).removeBundle(pluginImport.getId()); 315 } 316 } 317 fireStructureChanged(pluginImports, false); 318 } 319 } 320 321 @Override getLibraries()322 public IPluginLibrary[] getLibraries() { 323 IBundle bundle = getBundle(); 324 if (bundle == null) { 325 return new IPluginLibrary[0]; 326 } 327 if (libraries == null) { 328 libraries = new ArrayList<>(); 329 String value = bundle.getHeader(Constants.BUNDLE_CLASSPATH); 330 if (value != null) { 331 try { 332 ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, value); 333 for (ManifestElement element : elements) { 334 PluginLibrary library = new PluginLibrary(); 335 library.setModel(getModel()); 336 library.setInTheModel(true); 337 library.setParent(this); 338 library.load(element.getValue()); 339 libraries.add(library); 340 } 341 } catch (BundleException e) { 342 } 343 } 344 } 345 return libraries.toArray(new IPluginLibrary[libraries.size()]); 346 } 347 348 @Override getImports()349 public IPluginImport[] getImports() { 350 if (imports == null) { 351 imports = new ArrayList<>(); 352 BundleDescription description = model.getBundleDescription(); 353 if (description != null) { 354 BundleSpecification[] required = description.getRequiredBundles(); 355 for (BundleSpecification element : required) { 356 PluginImport importElement = new PluginImport(); 357 importElement.setModel(getModel()); 358 importElement.setInTheModel(true); 359 importElement.setParent(this); 360 imports.add(importElement); 361 importElement.load(element); 362 } 363 BundleDescription[] imported = PluginBase.getImportedBundles(description); 364 for (BundleDescription element : imported) { 365 PluginImport importElement = new PluginImport(); 366 importElement.setModel(getModel()); 367 importElement.setInTheModel(true); 368 importElement.setParent(this); 369 imports.add(importElement); 370 importElement.load(element); 371 } 372 } else { 373 IBundle bundle = getBundle(); 374 if (bundle != null) { 375 try { 376 String value = bundle.getHeader(Constants.REQUIRE_BUNDLE); 377 int bundleManifestVersion = getBundleManifestVersion(bundle); 378 if (value != null) { 379 ManifestElement[] elements = ManifestElement.parseHeader(Constants.REQUIRE_BUNDLE, value); 380 for (ManifestElement element : elements) { 381 PluginImport importElement = new PluginImport(); 382 importElement.setModel(getModel()); 383 importElement.setInTheModel(true); 384 importElement.setParent(this); 385 imports.add(importElement); 386 importElement.load(element, bundleManifestVersion); 387 } 388 } 389 } catch (BundleException e) { 390 } 391 } 392 } 393 } 394 return imports.toArray(new IPluginImport[imports.size()]); 395 } 396 397 @Override getProviderName()398 public String getProviderName() { 399 IBundle bundle = getBundle(); 400 return bundle == null ? null : bundle.getHeader(Constants.BUNDLE_VENDOR); 401 } 402 403 @Override setProviderName(String providerName)404 public void setProviderName(String providerName) throws CoreException { 405 ensureModelEditable(); 406 IBundle bundle = getBundle(); 407 if (bundle != null) { 408 String old = getProviderName(); 409 IManifestHeader header = bundle.getManifestHeader(Constants.BUNDLE_VENDOR); 410 if (header instanceof BundleVendorHeader) { 411 ((BundleVendorHeader) header).setVendor(providerName); 412 } else { 413 bundle.setHeader(Constants.BUNDLE_VENDOR, providerName); 414 } 415 model.fireModelObjectChanged(this, IPluginBase.P_PROVIDER, old, providerName); 416 } 417 } 418 419 @Override getVersion()420 public String getVersion() { 421 BundleDescription desc = model.getBundleDescription(); 422 if (desc != null) { 423 Version version = desc.getVersion(); 424 return (version != null) ? version.toString() : null; 425 } 426 return getValue(Constants.BUNDLE_VERSION, false); 427 } 428 429 @Override setVersion(String version)430 public void setVersion(String version) throws CoreException { 431 ensureModelEditable(); 432 IBundle bundle = getBundle(); 433 if (bundle != null) { 434 String old = getVersion(); 435 IManifestHeader header = bundle.getManifestHeader(Constants.BUNDLE_VERSION); 436 if (header instanceof BundleVersionHeader) { 437 ((BundleVersionHeader) header).setVersionRange(version); 438 } else { 439 bundle.setHeader(Constants.BUNDLE_VERSION, version); 440 } 441 model.fireModelObjectChanged(this, IPluginBase.P_VERSION, old, version); 442 } 443 } 444 445 @Override swap(IPluginLibrary l1, IPluginLibrary l2)446 public void swap(IPluginLibrary l1, IPluginLibrary l2) throws CoreException { 447 ensureModelEditable(); 448 if (libraries != null) { 449 int index1 = libraries.indexOf(l1); 450 int index2 = libraries.indexOf(l2); 451 libraries.set(index1, l2); 452 libraries.set(index2, l1); 453 Object header = getManifestHeader(Constants.BUNDLE_CLASSPATH); 454 if (header instanceof BundleClasspathHeader) { 455 ((BundleClasspathHeader) header).swap(index1, index2); 456 } 457 model.fireModelObjectChanged(this, P_IMPORT_ORDER, l1, l2); 458 } 459 } 460 fireStructureChanged(Object object, boolean added)461 protected void fireStructureChanged(Object object, boolean added) { 462 int type = (added) ? IModelChangedEvent.INSERT : IModelChangedEvent.REMOVE; 463 model.fireModelChanged(new ModelChangedEvent(model, type, new Object[] {object}, null)); 464 } 465 fireStructureChanged(Object[] objects, boolean added)466 protected void fireStructureChanged(Object[] objects, boolean added) { 467 int type = (added) ? IModelChangedEvent.INSERT : IModelChangedEvent.REMOVE; 468 model.fireModelChanged(new ModelChangedEvent(model, type, objects, null)); 469 } 470 471 @Override add(IPluginExtension extension)472 public void add(IPluginExtension extension) throws CoreException { 473 ensureModelEditable(); 474 IExtensions extensions = getExtensionsRoot(); 475 if (extensions == null) { 476 return; 477 } 478 extensions.add(extension); 479 480 // reset singleton 481 if (getExtensions().length == 1 && getExtensionPoints().length == 0) { 482 updateSingleton(true); 483 } 484 } 485 486 @Override add(IPluginExtensionPoint point)487 public void add(IPluginExtensionPoint point) throws CoreException { 488 ensureModelEditable(); 489 IExtensions extensions = getExtensionsRoot(); 490 if (extensions == null) { 491 return; 492 } 493 extensions.add(point); 494 495 //reset singleton 496 if (getExtensions().length == 0 && getExtensionPoints().length == 1) { 497 updateSingleton(true); 498 } 499 } 500 501 @Override getResourceString(String key)502 public String getResourceString(String key) { 503 return model.getResourceString(key); 504 } 505 506 @Override getExtensionPoints()507 public IPluginExtensionPoint[] getExtensionPoints() { 508 IExtensions extensions = getExtensionsRoot(); 509 if (extensions == null) { 510 return new IPluginExtensionPoint[0]; 511 } 512 return extensions.getExtensionPoints(); 513 } 514 515 @Override getExtensions()516 public IPluginExtension[] getExtensions() { 517 IExtensions extensions = getExtensionsRoot(); 518 if (extensions == null) { 519 return new IPluginExtension[0]; 520 } 521 return extensions.getExtensions(); 522 } 523 524 @Override getIndexOf(IPluginExtension e)525 public int getIndexOf(IPluginExtension e) { 526 IExtensions extensions = getExtensionsRoot(); 527 if (extensions == null) { 528 return -1; 529 } 530 return extensions.getIndexOf(e); 531 } 532 533 @Override remove(IPluginExtension extension)534 public void remove(IPluginExtension extension) throws CoreException { 535 ensureModelEditable(); 536 IExtensions extensions = getExtensionsRoot(); 537 if (extensions != null) { 538 extensions.remove(extension); 539 // reset singleton directive 540 if (getExtensions().length == 0 && getExtensionPoints().length == 0) { 541 updateSingleton(false); 542 } 543 } 544 } 545 546 @Override remove(IPluginExtensionPoint extensionPoint)547 public void remove(IPluginExtensionPoint extensionPoint) throws CoreException { 548 ensureModelEditable(); 549 IExtensions extensions = getExtensionsRoot(); 550 if (extensions != null) { 551 extensions.remove(extensionPoint); 552 // reset singleton directive 553 if (getExtensions().length == 0 && getExtensionPoints().length == 0) { 554 updateSingleton(false); 555 } 556 } 557 } 558 updateSingleton(boolean singleton)559 protected void updateSingleton(boolean singleton) { 560 IManifestHeader header = getManifestHeader(Constants.BUNDLE_SYMBOLICNAME); 561 if (header instanceof BundleSymbolicNameHeader) { 562 ((BundleSymbolicNameHeader) header).setSingleton(singleton); 563 } else { 564 if (singleton) { 565 String version = getBundle().getHeader(Constants.BUNDLE_MANIFESTVERSION); 566 if (version == null) 567 { 568 version = "1"; //$NON-NLS-1$ 569 } 570 String value = header.getValue(); 571 String singletonValue = null; 572 if (Integer.parseInt(version) >= 2) { 573 singletonValue = Constants.SINGLETON_DIRECTIVE + ":=true"; //$NON-NLS-1$ 574 } 575 else { 576 singletonValue = Constants.SINGLETON_DIRECTIVE + "=true"; //$NON-NLS-1$ 577 } 578 if (value.contains(singletonValue)) { 579 return; 580 } 581 getBundle().setHeader(Constants.BUNDLE_SYMBOLICNAME, value + "; " + singletonValue); //$NON-NLS-1$ 582 } 583 // No current need to remove singleton directive outside of text model. 584 } 585 } 586 587 @Override swap(IPluginExtension e1, IPluginExtension e2)588 public void swap(IPluginExtension e1, IPluginExtension e2) throws CoreException { 589 ensureModelEditable(); 590 IExtensions extensions = getExtensionsRoot(); 591 if (extensions != null) { 592 extensions.swap(e1, e2); 593 } 594 } 595 596 @Override swap(IPluginImport import1, IPluginImport import2)597 public void swap(IPluginImport import1, IPluginImport import2) throws CoreException { 598 ensureModelEditable(); 599 if (imports != null) { 600 int index1 = imports.indexOf(import1); 601 int index2 = imports.indexOf(import2); 602 imports.set(index1, import2); 603 imports.set(index2, import1); 604 Object header = getManifestHeader(Constants.REQUIRE_BUNDLE); 605 if (header instanceof RequireBundleHeader) { 606 ((RequireBundleHeader) header).swap(index1, index2); 607 } 608 model.fireModelObjectChanged(this, P_IMPORT_ORDER, import1, import2); 609 } 610 } 611 612 @Override getId()613 public String getId() { 614 return getValue(Constants.BUNDLE_SYMBOLICNAME, true); 615 } 616 617 // The key should be a manifest header key, and parse should be true if it needs to be parsed by ManifestElement.parseHeader() getValue(String key, boolean parse)618 protected String getValue(String key, boolean parse) { 619 IBundle bundle = getBundle(); 620 if (bundle == null) { 621 return null; 622 } 623 String value = bundle.getHeader(key); 624 if (value == null || !parse) { 625 return value; 626 } 627 try { 628 ManifestElement[] elements = ManifestElement.parseHeader(key, value); 629 if (elements.length > 0) { 630 return elements[0].getValue(); 631 } 632 } catch (BundleException e) { 633 } 634 return null; 635 } 636 637 @Override setId(String id)638 public void setId(String id) throws CoreException { 639 ensureModelEditable(); 640 IBundle bundle = getBundle(); 641 if (bundle != null) { 642 String old = getId(); 643 IManifestHeader header = bundle.getManifestHeader(Constants.BUNDLE_SYMBOLICNAME); 644 if (header instanceof BundleSymbolicNameHeader) { 645 ((BundleSymbolicNameHeader) header).setId(id); 646 } else { 647 bundle.setHeader(Constants.BUNDLE_SYMBOLICNAME, id); 648 } 649 model.fireModelObjectChanged(this, IIdentifiable.P_ID, old, id); 650 } 651 } 652 653 @Override getPluginModel()654 public IPluginModelBase getPluginModel() { 655 return model; 656 } 657 658 @Override getName()659 public String getName() { 660 return getValue(Constants.BUNDLE_NAME, false); 661 } 662 663 @Override setName(String name)664 public void setName(String name) throws CoreException { 665 ensureModelEditable(); 666 IBundle bundle = getBundle(); 667 if (bundle != null) { 668 String old = getName(); 669 IManifestHeader header = bundle.getManifestHeader(Constants.BUNDLE_NAME); 670 if (header instanceof BundleNameHeader) { 671 ((BundleNameHeader) header).setBundleName(name); 672 } else { 673 bundle.setHeader(Constants.BUNDLE_NAME, name); 674 } 675 model.fireModelObjectChanged(this, IPluginObject.P_NAME, old, name); 676 } 677 } 678 679 @Override isInTheModel()680 public boolean isInTheModel() { 681 return model != null; 682 } 683 684 @Override getTranslatedName()685 public String getTranslatedName() { 686 return getResourceString(getName()); 687 } 688 689 @Override getParent()690 public IPluginObject getParent() { 691 return null; 692 } 693 694 @Override getPluginBase()695 public IPluginBase getPluginBase() { 696 return this; 697 } 698 699 @Override isValid()700 public boolean isValid() { 701 IExtensions extensions = getExtensionsRoot(); 702 return getBundle() != null && getBundle().getHeader(Constants.BUNDLE_SYMBOLICNAME) != null && (extensions == null || extensions.isValid()); 703 } 704 705 @Override write(String indent, PrintWriter writer)706 public void write(String indent, PrintWriter writer) { 707 } 708 709 @Override setInTheModel(boolean inModel)710 public void setInTheModel(boolean inModel) { 711 } 712 getBundleManifestVersion(IBundle bundle)713 static public int getBundleManifestVersion(IBundle bundle) { 714 String version = bundle.getHeader(Constants.BUNDLE_MANIFESTVERSION); 715 if (version == null) { 716 return 1; // default to 1 717 } 718 try { 719 return Integer.parseInt(version); 720 } catch (NumberFormatException e) { 721 return 1; // default to 1 722 } 723 } 724 updateImport(IPluginImport iimport)725 public void updateImport(IPluginImport iimport) { 726 Object header = getManifestHeader(Constants.REQUIRE_BUNDLE); 727 if (header instanceof RequireBundleHeader && imports != null) { 728 ((RequireBundleHeader) header).updateBundle(imports.indexOf(iimport), iimport); 729 } 730 } 731 732 @Override getTargetVersion()733 public String getTargetVersion() { 734 return fTarget != null ? fTarget : TargetPlatformHelper.getTargetVersionString(); 735 } 736 737 @Override setTargetVersion(String target)738 public void setTargetVersion(String target) { 739 fTarget = target; 740 } 741 getIndexOf(IPluginImport targetImport)742 public int getIndexOf(IPluginImport targetImport) { 743 if (imports == null) { 744 return -1; 745 } 746 return imports.indexOf(targetImport); 747 } 748 getPreviousImport(IPluginImport targetImport)749 public IPluginImport getPreviousImport(IPluginImport targetImport) { 750 // Ensure we have imports 751 if (imports == null) { 752 return null; 753 } else if (imports.size() <= 1) { 754 return null; 755 } 756 // Get the index of the target import 757 int targetIndex = getIndexOf(targetImport); 758 // Validate index 759 if (targetIndex < 0) { 760 // Target import does not exist 761 return null; 762 } else if (targetIndex == 0) { 763 // Target import has no previous import 764 return null; 765 } 766 // 1 <= index < size() 767 // Get the previous import 768 IPluginImport previousImport = imports.get(targetIndex - 1); 769 770 return previousImport; 771 } 772 getNextImport(IPluginImport targetImport)773 public IPluginImport getNextImport(IPluginImport targetImport) { 774 // Ensure we have imports 775 if (imports == null) { 776 return null; 777 } else if (imports.size() <= 1) { 778 return null; 779 } 780 // Get the index of the target import 781 int targetIndex = getIndexOf(targetImport); 782 // Get the index of the last import 783 int lastIndex = imports.size() - 1; 784 // Validate index 785 if (targetIndex < 0) { 786 // Target import does not exist 787 return null; 788 } else if (targetIndex >= lastIndex) { 789 // Target import has no next element 790 return null; 791 } 792 // 0 <= index < last element < size() 793 // Get the next element 794 IPluginImport nextImport = imports.get(targetIndex + 1); 795 796 return nextImport; 797 } 798 add(IPluginImport iimport, int index)799 public void add(IPluginImport iimport, int index) throws CoreException { 800 ensureModelEditable(); 801 int importCount = 0; 802 if (imports != null) { 803 importCount = imports.size(); 804 } 805 // Validate index 806 if (index < 0) { 807 return; 808 } else if (index > importCount) { 809 return; 810 } 811 // 0 <= index <= importCount 812 // Add the element to the list 813 if (imports == null) { 814 // Intitialize the imports list by calling getImports() 815 getImports(); 816 // Add the import to the end of the list 817 addImport(iimport); 818 } else { 819 // Add the import to the list at the specified index 820 addImport(iimport, index); 821 } 822 // Fire event 823 fireStructureChanged(iimport, true); 824 } 825 826 /** 827 * @param iimport 828 * @param index 829 */ addImport(IPluginImport iimport, int index)830 private void addImport(IPluginImport iimport, int index) { 831 // Get the header 832 IManifestHeader header = getManifestHeader(Constants.REQUIRE_BUNDLE); 833 if ((header instanceof RequireBundleHeader) == false) { 834 addImport(iimport); 835 } else { 836 // Add the import to the local container 837 imports.add(index, iimport); 838 // Add the import to the header 839 ((RequireBundleHeader) header).addBundle(iimport, index); 840 } 841 } 842 add(IPluginLibrary library, int index)843 public void add(IPluginLibrary library, int index) throws CoreException { 844 ensureModelEditable(); 845 int libraryCount = 0; 846 if (libraries != null) { 847 libraryCount = libraries.size(); 848 } 849 // Validate index 850 if (index < 0) { 851 return; 852 } else if (index > libraryCount) { 853 return; 854 } 855 // 0 <= index <= libraryCount 856 if (libraries == null) { 857 // Intitialize the library list by calling getLibraries() 858 getLibraries(); 859 } 860 // Get the header 861 IManifestHeader header = getManifestHeader(Constants.BUNDLE_CLASSPATH); 862 if ((header instanceof BundleClasspathHeader) == false) { 863 // Add the library to the local container 864 libraries.add(library); 865 // Add the library to a newly created header 866 addLibrary(library, header); 867 } else { 868 // Add the library to the local container at the specified index 869 libraries.add(index, library); 870 // Add the library to the existing header at the specified index 871 ((BundleClasspathHeader) header).addLibrary(library.getName(), index); 872 } 873 // Fire event 874 fireStructureChanged(library, true); 875 } 876 getIndexOf(IPluginLibrary targetLibrary)877 public int getIndexOf(IPluginLibrary targetLibrary) { 878 if (libraries == null) { 879 return -1; 880 } 881 return libraries.indexOf(targetLibrary); 882 } 883 getNextLibrary(IPluginLibrary targetLibrary)884 public IPluginLibrary getNextLibrary(IPluginLibrary targetLibrary) { 885 // Ensure we have libraries 886 if (libraries == null) { 887 return null; 888 } else if (libraries.size() <= 1) { 889 return null; 890 } 891 // Get the index of the target library 892 int targetIndex = getIndexOf(targetLibrary); 893 // Get the index of the last library 894 int lastIndex = libraries.size() - 1; 895 // Validate index 896 if (targetIndex < 0) { 897 // Target library does not exist 898 return null; 899 } else if (targetIndex >= lastIndex) { 900 // Target library has no next element 901 return null; 902 } 903 // 0 <= index < last element < size() 904 // Get the next library 905 IPluginLibrary nextLibrary = libraries.get(targetIndex + 1); 906 907 return nextLibrary; 908 } 909 getPreviousLibrary(IPluginLibrary targetLibrary)910 public IPluginLibrary getPreviousLibrary(IPluginLibrary targetLibrary) { 911 // Ensure we have libraries 912 if (libraries == null) { 913 return null; 914 } else if (libraries.size() <= 1) { 915 return null; 916 } 917 // Get the index of the target library 918 int targetIndex = getIndexOf(targetLibrary); 919 // Validate index 920 if (targetIndex < 0) { 921 // Target library does not exist 922 return null; 923 } else if (targetIndex == 0) { 924 // Target library has no previous library 925 return null; 926 } 927 // 1 <= index < size() 928 // Get the previous library 929 IPluginLibrary previousLibrary = libraries.get(targetIndex - 1); 930 931 return previousLibrary; 932 } 933 ensureModelEditable()934 protected void ensureModelEditable() throws CoreException { 935 if (!getModel().isEditable()) { 936 throwCoreException(PDECoreMessages.PluginObject_readOnlyChange); 937 } 938 } 939 throwCoreException(String message)940 protected void throwCoreException(String message) throws CoreException { 941 Status status = new Status(IStatus.ERROR, PDECore.PLUGIN_ID, IStatus.OK, message, null); 942 CoreException ce = new CoreException(status); 943 ce.fillInStackTrace(); 944 throw ce; 945 } 946 947 } 948