| 1 11 package org.eclipse.update.internal.operations; 12 13 import java.io.File ; 17 import java.io.IOException ; 18 import java.net.URL ; 19 import java.net.URLConnection ; 20 import java.util.ArrayList ; 21 import java.util.Collections ; 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.Set ; 25 import java.util.StringTokenizer ; 26 27 import org.eclipse.core.runtime.CoreException; 28 import org.eclipse.core.runtime.IProduct; 29 import org.eclipse.core.runtime.IStatus; 30 import org.eclipse.core.runtime.MultiStatus; 31 import org.eclipse.core.runtime.Platform; 32 import org.eclipse.core.runtime.PluginVersionIdentifier; 33 import org.eclipse.osgi.util.NLS; 34 import org.eclipse.update.configuration.IConfiguredSite; 35 import org.eclipse.update.configuration.IInstallConfiguration; 36 import org.eclipse.update.configuration.ILocalSite; 37 import org.eclipse.update.configurator.ConfiguratorUtils; 38 import org.eclipse.update.configurator.IPlatformConfiguration; 39 import org.eclipse.update.core.IFeature; 40 import org.eclipse.update.core.IFeatureReference; 41 import org.eclipse.update.core.IImport; 42 import org.eclipse.update.core.IIncludedFeatureReference; 43 import org.eclipse.update.core.IPluginEntry; 44 import org.eclipse.update.core.ISiteFeatureReference; 45 import org.eclipse.update.core.IURLEntry; 46 import org.eclipse.update.core.SiteManager; 47 import org.eclipse.update.core.VersionedIdentifier; 48 import org.eclipse.update.internal.configurator.PlatformConfiguration; 49 import org.eclipse.update.internal.core.Messages; 50 import org.eclipse.update.internal.core.UpdateCore; 51 import org.eclipse.update.operations.IInstallFeatureOperation; 52 import org.eclipse.update.operations.IOperationValidator; 53 import org.osgi.framework.Bundle; 54 55 58 public class OperationValidator implements IOperationValidator { 59 63 public IStatus validatePlatformConfigValid() { 64 ArrayList status = new ArrayList (1); 65 checkPlatformWasModified(status); 66 67 if (status.size() > 0) 69 return createMultiStatus(Messages.ActivityConstraints_rootMessage, status, IStatus.ERROR); 70 return null; 71 } 72 73 79 public IStatus validatePendingInstall( 80 IFeature oldFeature, 81 IFeature newFeature) { 82 ArrayList beforeStatus = new ArrayList (); 84 validateInitialState(beforeStatus); 85 86 ArrayList status = new ArrayList (); 88 checkPlatformWasModified(status); 89 validateInstall(oldFeature, newFeature, status); 90 91 return createCombinedReportStatus(beforeStatus, status); 93 } 94 95 98 public IStatus validatePendingUnconfig(IFeature feature) { 99 ArrayList beforeStatus = new ArrayList (); 101 validateInitialState(beforeStatus); 102 103 ArrayList status = new ArrayList (); 105 checkPlatformWasModified(status); 106 validateUnconfigure(feature, status); 107 108 return createCombinedReportStatus(beforeStatus, status); 110 } 111 112 115 public IStatus validatePendingConfig(IFeature feature) { 116 ArrayList beforeStatus = new ArrayList (); 118 validateInitialState(beforeStatus); 119 120 ArrayList status = new ArrayList (); 122 checkPlatformWasModified(status); 123 validateConfigure(feature, status); 124 125 return createCombinedReportStatus(beforeStatus, status); 127 } 128 129 132 public IStatus validatePendingReplaceVersion( 133 IFeature feature, 134 IFeature anotherFeature) { 135 ArrayList beforeStatus = new ArrayList (); 137 validateInitialState(beforeStatus); 138 139 ArrayList status = new ArrayList (); 141 checkPlatformWasModified(status); 142 validateReplaceVersion(feature, anotherFeature, status); 143 144 return createCombinedReportStatus(beforeStatus, status); 146 } 147 148 149 152 public IStatus validatePendingRevert(IInstallConfiguration config) { 153 ArrayList beforeStatus = new ArrayList (); 155 validateInitialState(beforeStatus); 156 157 ArrayList status = new ArrayList (); 159 checkPlatformWasModified(status); 160 validateRevert(config, status); 161 162 return createCombinedReportStatus(beforeStatus, status); 164 } 165 166 170 public IStatus validatePendingChanges(IInstallFeatureOperation[] jobs) { 171 ArrayList beforeStatus = new ArrayList (); 173 validateInitialState(beforeStatus); 174 checkPlatformWasModified(beforeStatus); 175 176 ArrayList status = new ArrayList (); 178 validatePendingChanges(jobs, status, beforeStatus); 179 180 return createCombinedReportStatus(beforeStatus, status); 182 } 183 184 188 public RequiredFeaturesResult getRequiredFeatures(IInstallFeatureOperation[] jobs) { 189 190 RequiredFeaturesResult requiredFeaturesResult = new RequiredFeaturesResult(); 191 ArrayList beforeStatus = new ArrayList (); 193 validateInitialState(beforeStatus); 194 checkPlatformWasModified(beforeStatus); 195 196 ArrayList status = new ArrayList (); 198 Set requiredFeatures = validatePendingChanges(jobs, status, beforeStatus); 199 200 requiredFeaturesResult.setRequiredFeatures(requiredFeatures); 203 requiredFeaturesResult.setStatus(createCombinedReportStatus(beforeStatus, status)); 204 return requiredFeaturesResult; 205 } 206 207 210 public IStatus validateCurrentState() { 211 ArrayList status = new ArrayList (); 213 checkPlatformWasModified(status); 214 validateInitialState(status); 215 216 if (status.size() > 0) 218 return createMultiStatus(Messages.ActivityConstraints_rootMessage, status, IStatus.ERROR); 219 return null; 220 } 221 222 225 private static void validateInitialState(ArrayList status) { 226 try { 227 ArrayList features = computeFeatures(); 228 checkConstraints(features, status); 231 } catch (CoreException e) { 232 status.add(e.getStatus()); 233 } 234 } 235 236 239 private static void validateUnconfigure( 240 IFeature feature, 241 ArrayList status) { 242 try { 243 checkSiteReadOnly(feature,status); 244 ArrayList features = computeFeatures(); 245 features = computeFeaturesAfterOperation(features, null, feature); 246 checkConstraints(features, status); 247 } catch (CoreException e) { 248 status.add(e.getStatus()); 249 } 250 } 251 252 253 256 private static void validateConfigure(IFeature feature, ArrayList status) { 257 try { 258 checkSiteReadOnly(feature,status); 259 ArrayList features = computeFeatures(); 260 checkOptionalChildConfiguring(feature, status); 261 checkForCycles(feature, null, features); 262 features = computeFeaturesAfterOperation(features, feature, null); 263 checkConstraints(features, status); 264 265 } catch (CoreException e) { 266 status.add(e.getStatus()); 267 } 268 } 269 270 273 private static void validateReplaceVersion( 274 IFeature feature, 275 IFeature anotherFeature, 276 ArrayList status) { 277 try { 278 checkSiteReadOnly(feature,status); 279 ArrayList features = computeFeatures(); 280 checkForCycles(feature, null, features); 281 features = 282 computeFeaturesAfterOperation( 283 features, 284 anotherFeature, 285 feature); 286 checkConstraints(features, status); 287 } catch (CoreException e) { 288 status.add(e.getStatus()); 289 } 290 } 291 292 295 private static void validateInstall( 296 IFeature oldFeature, 297 IFeature newFeature, 298 ArrayList status) { 299 try { 300 checkSiteReadOnly(oldFeature,status); 301 ArrayList features = computeFeatures(); 302 checkForCycles(newFeature, null, features); 303 features = 304 computeFeaturesAfterOperation(features, newFeature, oldFeature); 305 checkConstraints(features, status); 306 checkLicense(newFeature, status); 307 } catch (CoreException e) { 308 status.add(e.getStatus()); 309 } 310 } 311 312 315 private static void validateRevert( 316 IInstallConfiguration config, 317 ArrayList status) { 318 try { 319 ArrayList features = computeFeaturesAfterRevert(config); 324 checkConstraints(features, status); 325 checkRevertConstraints(features, status); 326 327 } catch (CoreException e) { 328 status.add(e.getStatus()); 329 } 330 } 331 332 333 336 private static Set validatePendingChanges( 337 IInstallFeatureOperation[] jobs, 338 ArrayList status, 339 ArrayList beforeStatus) { 340 try { 341 ArrayList features = computeFeatures(); 342 ArrayList savedFeatures = features; 343 int nexclusives = 0; 344 345 ArrayList tmpStatus = new ArrayList (); 347 for (int i = 0; i < jobs.length; i++) { 348 IInstallFeatureOperation job = jobs[i]; 349 350 IFeature newFeature = job.getFeature(); 351 IFeature oldFeature = job.getOldFeature(); 352 checkLicense(newFeature, status); 353 if (jobs.length > 1 && newFeature.isExclusive()) { 354 nexclusives++; 355 status.add( 356 createStatus( 357 newFeature, 358 FeatureStatus.CODE_EXCLUSIVE, 359 Messages.ActivityConstraints_exclusive)); 360 continue; 361 } 362 checkForCycles(newFeature, null, features); 363 features = 364 computeFeaturesAfterOperation( 365 features, 366 newFeature, 367 oldFeature); 368 } 369 if (nexclusives > 0) 370 return Collections.EMPTY_SET; 371 checkConstraints(features, tmpStatus); 372 if (tmpStatus.size() == 0) return Collections.EMPTY_SET; 374 375 features = savedFeatures; 377 for (int i = 0; i < jobs.length; i++) { 378 IInstallFeatureOperation job = jobs[i]; 379 IFeature newFeature = job.getFeature(); 380 IFeature oldFeature = job.getOldFeature(); 381 382 features = 383 computeFeaturesAfterOperation( 384 features, 385 newFeature, 386 oldFeature); 387 388 Set result = checkConstraints(features, status); 389 if (status.size() > 0 390 && !isBetterStatus(beforeStatus, status)) { 391 return result; 399 } 400 } 401 } catch (CoreException e) { 402 status.add(e.getStatus()); 403 } 404 405 return Collections.EMPTY_SET; 406 } 407 408 private static void checkPlatformWasModified(ArrayList status) { 409 try { 410 IPlatformConfiguration platformConfig = ConfiguratorUtils.getCurrentPlatformConfiguration(); 412 413 long currentTimeStamp = platformConfig.getChangeStamp(); 414 if (platformConfig instanceof PlatformConfiguration) 416 currentTimeStamp = ((PlatformConfiguration)platformConfig).getConfiguration().lastModified(); 417 418 URL platformXML = platformConfig.getConfigurationLocation(); 420 long actualTimeStamp = currentTimeStamp; 421 if ("file".equals(platformXML.getProtocol())) actualTimeStamp = new File (platformXML.getFile()).lastModified(); 423 else { 424 URLConnection connection = platformXML.openConnection(); 425 actualTimeStamp = connection.getLastModified(); 426 } 427 if (currentTimeStamp != actualTimeStamp) 428 status.add(createStatus( 429 null, 430 FeatureStatus.CODE_OTHER, 431 Messages.ActivityConstraints_platformModified)); 432 } catch (IOException e) { 433 } 435 } 436 437 private static void checkSiteReadOnly(IFeature feature, ArrayList status) { 438 if(feature == null){ 439 return; 440 } 441 IConfiguredSite csite = feature.getSite().getCurrentConfiguredSite(); 442 if (csite != null && !csite.isUpdatable()) 443 status.add(createStatus(feature, FeatureStatus.CODE_OTHER, 444 NLS.bind(Messages.ActivityConstraints_readOnly, (new String [] { csite.getSite().getURL().toExternalForm() })))); 445 } 446 447 450 private static ArrayList computeFeatures() throws CoreException { 451 return computeFeatures(true); 452 } 453 456 private static ArrayList computeFeatures(boolean configuredOnly) 457 throws CoreException { 458 ArrayList features = new ArrayList (); 459 ILocalSite localSite = SiteManager.getLocalSite(); 460 IInstallConfiguration config = localSite.getCurrentConfiguration(); 461 IConfiguredSite[] csites = config.getConfiguredSites(); 462 463 for (int i = 0; i < csites.length; i++) { 464 IConfiguredSite csite = csites[i]; 465 466 IFeatureReference[] crefs; 467 468 if (configuredOnly) 469 crefs = csite.getConfiguredFeatures(); 470 else 471 crefs = csite.getSite().getFeatureReferences(); 472 for (int j = 0; j < crefs.length; j++) { 473 IFeatureReference cref = crefs[j]; 474 IFeature cfeature = cref.getFeature(null); 475 features.add(cfeature); 476 } 477 } 478 479 return features; 480 } 481 482 486 public static ArrayList computeFeatureSubtree( 487 IFeature top, 488 IFeature feature, 489 ArrayList features, 490 boolean tolerateMissingChildren, 491 ArrayList configuredFeatures, 492 ArrayList visitedFeatures) 493 throws CoreException { 494 495 if (top == null) 497 return features; 498 if (feature == null) 499 feature = top; 500 if (features == null) 501 features = new ArrayList (); 502 if (visitedFeatures == null) 503 visitedFeatures = new ArrayList (); 504 505 if (visitedFeatures.contains(feature)) { 507 IStatus status = 508 createStatus(top, FeatureStatus.CODE_CYCLE, Messages.ActivityConstraints_cycle); 509 throw new CoreException(status); 510 } else { 511 visitedFeatures.add(feature); 513 } 514 515 if (!features.contains(feature)) 517 features.add(feature); 518 IIncludedFeatureReference[] children = 519 feature.getIncludedFeatureReferences(); 520 for (int i = 0; i < children.length; i++) { 521 try { 522 IFeature child = UpdateUtils.getIncludedFeature(feature, children[i]); 523 features = 524 computeFeatureSubtree( 525 top, 526 child, 527 features, 528 tolerateMissingChildren, 529 null, 530 visitedFeatures); 531 } catch (CoreException e) { 532 if (!children[i].isOptional() && !tolerateMissingChildren) 533 throw e; 534 } 535 } 536 visitedFeatures.remove(feature); 538 return features; 539 } 540 541 private static void checkLicense(IFeature feature, ArrayList status) { 542 IURLEntry licenseEntry = feature.getLicense(); 543 if (licenseEntry != null) { 544 String license = licenseEntry.getAnnotation(); 545 if (license != null && license.trim().length() > 0) 546 return; 547 } 548 status.add( 549 createStatus(feature, FeatureStatus.CODE_OTHER, Messages.ActivityConstraints_noLicense)); 550 } 551 552 555 private static ArrayList computeFeaturesAfterOperation( 556 ArrayList features, 557 IFeature add, 558 IFeature remove) 559 throws CoreException { 560 561 ArrayList addTree = computeFeatureSubtree(add, null, null, false, 562 563 features, null); 564 ArrayList removeTree = 565 computeFeatureSubtree( 566 remove, 567 null, 568 null, 569 true , 570 null, 571 null 572 ); 573 if (remove != null) { 574 contributePatchesFor(removeTree, features, removeTree); 577 } 578 579 if (remove != null) 580 features.removeAll(removeTree); 581 582 if (add != null) 583 features.addAll(addTree); 584 585 return features; 586 } 587 588 private static void contributePatchesFor( 589 ArrayList removeTree, 590 ArrayList features, 591 ArrayList result) 592 throws CoreException { 593 594 for (int i = 0; i < removeTree.size(); i++) { 595 IFeature feature = (IFeature) removeTree.get(i); 596 contributePatchesFor(feature, features, result); 597 } 598 } 599 600 private static void contributePatchesFor( 601 IFeature feature, 602 ArrayList features, 603 ArrayList result) 604 throws CoreException { 605 for (int i = 0; i < features.size(); i++) { 606 IFeature candidate = (IFeature) features.get(i); 607 if (UpdateUtils.isPatch(feature, candidate)) { 608 ArrayList removeTree = 609 computeFeatureSubtree(candidate, null, null, true,null,null); 610 result.addAll(removeTree); 611 } 612 } 613 } 614 615 619 private static ArrayList computeFeaturesAfterRevert(IInstallConfiguration config) 620 throws CoreException { 621 622 ArrayList list = new ArrayList (); 623 IConfiguredSite[] csites = config.getConfiguredSites(); 624 for (int i = 0; i < csites.length; i++) { 625 IConfiguredSite csite = csites[i]; 626 IFeatureReference[] features = csite.getConfiguredFeatures(); 627 for (int j = 0; j < features.length; j++) { 628 list.add(features[j].getFeature(null)); 629 } 630 } 631 return list; 632 } 633 634 635 636 639 private static ArrayList computePluginsForFeatures(ArrayList features) 640 throws CoreException { 641 if (features == null) 642 return new ArrayList (); 643 644 HashMap plugins = new HashMap (); 645 for (int i = 0; i < features.size(); i++) { 646 IFeature feature = (IFeature) features.get(i); 647 IPluginEntry[] entries = feature.getPluginEntries(); 648 for (int j = 0; j < entries.length; j++) { 649 IPluginEntry entry = entries[j]; 650 plugins.put(entry.getVersionedIdentifier(), entry); 651 } 652 } 653 ArrayList result = new ArrayList (); 654 result.addAll(plugins.values()); 655 return result; 656 } 657 658 659 666 private static void checkForCycles( 667 IFeature feature, 668 ArrayList candidates, 669 ArrayList configuredFeatures) 670 throws CoreException { 671 672 if (feature == null) 674 return; 675 if (configuredFeatures == null) 676 configuredFeatures = new ArrayList (); 677 if (candidates == null) 678 candidates = new ArrayList (); 679 680 if (candidates.contains(feature)) { 682 String msg = NLS.bind(Messages.ActivityConstraints_cycle, (new String [] {feature.getLabel(), 683 feature.getVersionedIdentifier().toString()})); 684 IStatus status = createStatus(feature, FeatureStatus.CODE_CYCLE, msg); 685 throw new CoreException(status); 686 } 687 688 candidates.add(feature); 690 691 IIncludedFeatureReference[] children = 693 feature.getIncludedFeatureReferences(); 694 for (int i = 0; i < children.length; i++) { 695 try { 696 IFeature child = UpdateUtils.getIncludedFeature(feature, children[i]); 697 checkForCycles(child, candidates, configuredFeatures); 698 } catch (CoreException e) { 699 if (!children[i].isOptional()) 700 throw e; 701 } 702 } 703 candidates.remove(feature); 705 } 706 707 710 private static Set checkConstraints(ArrayList features, ArrayList status) 711 throws CoreException { 712 if (features == null) 713 return Collections.EMPTY_SET; 714 715 ArrayList plugins = computePluginsForFeatures(features); 716 717 checkEnvironment(features, status); 718 checkPlatformFeature(features, plugins, status); 719 checkPrimaryFeature(features, plugins, status); 720 return checkPrereqs(features, plugins, status); 721 } 722 723 727 private static void checkEnvironment( 728 ArrayList features, 729 ArrayList status) { 730 731 String os = Platform.getOS(); 732 String ws = Platform.getWS(); 733 String arch = Platform.getOSArch(); 734 735 for (int i = 0; i < features.size(); i++) { 736 IFeature feature = (IFeature) features.get(i); 737 ArrayList fos = createList(feature.getOS()); 738 ArrayList fws = createList(feature.getWS()); 739 ArrayList farch = createList(feature.getOSArch()); 740 741 if (fos.size() > 0) { 742 if (!fos.contains(os)) { 743 IStatus s = 744 createStatus(feature, FeatureStatus.CODE_ENVIRONMENT, Messages.ActivityConstraints_os); 745 if (!status.contains(s)) 746  
|