1 19 20 package org.netbeans.modules.autoupdate; 21 22 import java.util.*; 23 import java.util.logging.Level ; 24 import java.util.logging.Logger ; 25 import org.openide.DialogDisplayer; 26 27 import org.openide.util.NbBundle; 28 import org.openide.NotifyDescriptor; 29 import org.openide.modules.ModuleInfo; 30 import org.openide.modules.Dependency; 31 import org.openide.modules.SpecificationVersion; 32 33 37 class DependencyChecker extends Object { 38 39 40 DependencyChecker() { 41 } 42 43 private static final Logger err = Logger.getLogger("org.netbeans.modules.autoupdate"); 45 48 Collection modulesToAdd( ModuleUpdate toAdd, Enumeration selected, List group, StringBuffer dontAddModuleName ) { 49 err.log(Level.FINE, 50 "DO modulesToAdd: " + toAdd.getCodeNameBase() + "[L10N? " + 51 (toAdd instanceof L10NUpdate) + "], group: " + group + 52 ", dontAddModuleName: " + dontAddModuleName); 53 Collection result = new ArrayList(); 54 checkDependencies( toAdd.getRemoteModule(), result, selected, group, dontAddModuleName, toAdd.getLocalModule() != null ); 55 if (err.isLoggable(Level.FINE)) { 56 String res = ""; 57 Iterator it = result.iterator (); 58 while (it.hasNext ()) { 59 ModuleUpdate mu = (ModuleUpdate) it.next (); 60 res = res + mu.getCodeNameBase () + "[L10N? " + (mu instanceof L10NUpdate) + "], "; 61 err.log(Level.FINE, 62 "modulesToAdd: " + toAdd.getCodeNameBase() + 63 ", RETURNS: " + res); 64 } 65 } 66 67 err.log(Level.FINE, 69 "Do find localization for " + toAdd.getCodeNameBase() + 70 " on locale " + Locale.getDefault()); 71 checkFreeLocalizationDependency (toAdd, Locale.getDefault ().toString (), result, selected, group); 72 73 return result; 74 } 75 76 79 Collection modulesToRemove( ModuleUpdate toRemove, ModuleUpdate toReplace ) { 80 Collection result = new ArrayList(); 81 checkReverseDependencies( toRemove.getRemoteModule(), result, toReplace ); 82 return result; 83 } 84 85 88 private boolean checkDependencies( ModuleInfo md, Collection result, Enumeration selected, List group, 89 StringBuffer dontAddModuleName, boolean isUpgrade ) { 90 91 Set depsS = md.getDependencies(); 93 Dependency[] deps = (Dependency[])depsS.toArray(new Dependency[depsS.size()]); 94 boolean[] satisfied = new boolean [ deps.length ]; 96 97 ModuleInfo[] installedModules = Updates.getInstalledModules(); 99 ModuleInfo[] installedPatches = Updates.getInstalledPatches(); 100 101 for ( int j = 0; j < deps.length; j++ ) { 103 104 if (deps[j].getType() == Dependency.TYPE_MODULE || deps[j].getType() == Dependency.TYPE_REQUIRES) { 106 107 boolean ok = false; 108 109 for (int i = 0; i < installedModules.length; i++) { 111 ok = checkModuleDependency ( deps[j], installedModules[i] ); 112 113 if ( ok ) 114 break; 115 } 116 117 if ( !ok ) { 118 for (int i = 0; i < installedPatches.length; i++) { 120 ok = checkModuleDependency ( deps[j], installedPatches[i] ); 121 if ( ok ) 122 break; 123 } 124 } 125 126 if ( !ok && selected != null ) { 129 130 while ( selected.hasMoreElements() ) { 131 ModuleUpdate mu = (ModuleUpdate)selected.nextElement(); 132 if (mu instanceof L10NUpdate) { 133 continue; 134 } 135 136 ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); 137 138 if ( ok ) { 139 if ( !result.contains( mu ) ) { 140 err.log(Level.FINE, 141 " ADDED[SELECTED]: " + 142 mu.getCodeNameBase() + "[L10N? " + 143 (mu instanceof L10NUpdate) + "]: DEP: " + 144 deps[j]); 145 result.add( mu ); 146 } 147 break; 148 } 149 } 150 } 151 152 if ( !ok && group != null ) { 153 154 Iterator it = group.iterator(); 155 while ( it.hasNext() ) { 156 ModuleUpdate mu = (ModuleUpdate)it.next(); 157 if (mu instanceof L10NUpdate) { 158 continue; 159 } 160 161 162 ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); 163 if ( ok ) { 164 if ( !result.contains( mu ) ) { 165 err.log(Level.FINE, 166 " ADDED[GROUP]: " + 167 mu.getCodeNameBase() + "[L10N? " + 168 (mu instanceof L10NUpdate) + "]: DEP: " + 169 deps[j]); 170 result.add( mu ); 171 } 172 break; 173 } 174 } 175 } 176 177 if ( !ok ) { 178 179 Iterator it = Wizard.getAllModules().iterator(); 180 while ( it.hasNext() ) { 181 ModuleUpdate mu = (ModuleUpdate)it.next(); 182 if (mu instanceof L10NUpdate) { 183 continue; 184 } 185 186 187 ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); 188 189 if ( ok ) { 190 if ( !result.contains( mu ) ) { 191 err.log(Level.FINE, 192 " ADDED[ALL]: " + mu.getCodeNameBase() + 193 "[L10N? " + (mu instanceof L10NUpdate) + 194 "]: DEP: " + deps[j]); 195 result.add( mu ); 196 } 197 break; 198 } 199 } 200 } 201 202 if ( !ok ) 203 satisfied[j] = false; 204 else 205 satisfied[j] = true; 206 } 207 else if ( deps[j].getType() == Dependency.TYPE_IDE ) { 209 if ( checkIdeDependency ( deps[j], IdeDescription.getIdeDescription() ) ) { 211 satisfied[j] = true; 212 } 213 else { 214 Iterator it = Wizard.getAllModules().iterator(); 216 boolean ok = false; 217 while ( it.hasNext() ) { 218 ModuleUpdate mu = (ModuleUpdate)it.next(); 219 if (mu instanceof L10NUpdate) { 220 continue; 221 } 222 223 224 ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); 225 if ( ok ) { 226 if ( !result.contains( mu ) ) { 227 err.log(Level.FINE, 228 " ADDED[GROUP]: " + 229 mu.getCodeNameBase() + "[L10N? " + 230 (mu instanceof L10NUpdate) + "]: DEP: " + 231 deps[j]); 232 result.add( mu ); 233 } 234 break; 235 } 236 } 237 satisfied[j] = ok; 238 } 239 } 240 else satisfied[j] = true; 242 } 243 244 StringBuffer sb = new StringBuffer ( 280 ); 245 sb.append (getBundle ("MSG_NotSatisfied")); sb.append (NbBundle.getMessage (DependencyChecker.class, "TXT_DependencyChecker_Module", md.getDisplayName (), md.getCodeName ())); 248 int notSatisfied = 0; 249 250 for ( int j = 0; j < deps.length; j++ ) { 252 if ( !satisfied[j] ) { 253 sb.append( deps[j] + "\n"); notSatisfied++; 255 } 256 } 257 258 StringBuffer sbbroken = null; 259 if ( isUpgrade ) { 260 List brokenlist = checkBrokenImplDependency( md, result ); 263 if ( brokenlist.size() > 0 ) { 264 sbbroken = new StringBuffer ( 280 ); 265 sbbroken.append (NbBundle.getMessage (DependencyChecker.class, "TXT_BrokenDependencyChecker_Module", md.getDisplayName (), md.getCodeName ())); sbbroken.append( getBundle( "MSG_BadsList" ) ); Iterator it = brokenlist.iterator(); 268 while ( it.hasNext() ) { 269 sbbroken.append (((ModuleInfo) it.next()).getCodeName() + "\n"); } 271 sbbroken.append( getBundle( "MSG_IncludeBadsAnyway" ) ); } 273 } 274 275 if ( notSatisfied == 0 && sbbroken == null ) 276 return true; 277 278 if ( notSatisfied > 0 ) { 279 sb.append( getBundle( "MSG_IncludeAnyway" ) ); NotifyDescriptor.Confirmation nd = new NotifyDescriptor.Confirmation( 281 sb.toString(), 282 NotifyDescriptor.YES_NO_OPTION, 283 NotifyDescriptor.ERROR_MESSAGE ); 284 285 if ( ! DialogDisplayer.getDefault().notify( nd ).equals( NotifyDescriptor.YES_OPTION ) ) { 286 dontAddModuleName.append( md.getDisplayName() ); 287 return false; 288 } 289 } 290 if ( sbbroken != null ) { 291 NotifyDescriptor.Confirmation nd = new NotifyDescriptor.Confirmation( 292 sbbroken.toString(), 293 NotifyDescriptor.YES_NO_OPTION, 294 NotifyDescriptor.ERROR_MESSAGE ); 295 296 if ( ! DialogDisplayer.getDefault().notify( nd ).equals( NotifyDescriptor.YES_OPTION ) ) 297 dontAddModuleName.append( md.getDisplayName() ); 298 } 299 300 return false; 301 } 302 303 304 307 boolean checkReverseDependencies( ModuleInfo module, Collection result, ModuleUpdate toReplace ) { 308 309 ModuleInfo[] installedModules = Updates.getInstalledModules(); 311 ModuleInfo[] installedPatches = Updates.getInstalledPatches(); 312 313 Iterator it = Wizard.getAllModules().iterator(); 315 while ( it.hasNext() ) { 316 ModuleUpdate mu = (ModuleUpdate)it.next(); 317 318 319 322 ModuleInfo md = mu.getRemoteModule(); 323 Set depsS = md.getDependencies(); 324 Dependency[] deps = (Dependency[])depsS.toArray(new Dependency[depsS.size()]); 325 326 boolean moduleOk = true; 328 for ( int j = 0; j < deps.length; j++ ) { 329 330 331 332 if ( (deps[j].getType() == Dependency.TYPE_MODULE && 333 (deps[j].getName() + "/").startsWith( module.getCodeNameBase() + "/" )) || (deps[j].getType() == Dependency.TYPE_REQUIRES && 335 Arrays.asList(module.getProvides()).contains(deps[j].getName())) ) { 336 337 boolean ok = false; 338 339 for (int k = 0; k < installedModules.length; k++) { 341 ok = checkModuleDependency ( deps[j], installedModules[k] ); 342 if ( ok ) 343 break; 344 } 345 346 if ( !ok && toReplace != null ) 348 ok = checkModuleDependency ( deps[j], toReplace.getRemoteModule() ); 349 350 if ( !ok ) 352 for (int k = 0; k < installedPatches.length; k++) { 353 ok = checkModuleDependency ( deps[j], installedPatches[k] ); 354 if ( ok ) 355 break; 356 } 357 358 359 if ( !ok ) { 361 moduleOk = false; 362 break; 363 } 364 } 365 else if ( deps[j].getType() == Dependency.TYPE_IDE && 366 deps[j].getName().equals( module.getCodeName() ) ) { 368 369 if ( !checkModuleDependency ( deps[j], IdeDescription.getIdeDescription() ) ) { 371 moduleOk = false; 372 break; 373 } 374 } 375 } 376 377 if ( !moduleOk ) { 378 if ( ! result.contains( mu ) ) { 379 result.add( mu ); 380 } 382 } 383 } 384 385 return result.size() == 0; 386 } 387 388 389 391 static boolean checkModuleDependency ( Dependency dep, 392 ModuleInfo otherModule ) { 393 394 if (dep.getType() == Dependency.TYPE_REQUIRES) { 395 return Arrays.asList(otherModule.getProvides()).contains(dep.getName()); 396 } 397 398 String depName = dep.getName(); 399 400 if ( depName.equals (otherModule.getCodeName ())) { 401 if ( dep.getComparison() == Dependency.COMPARE_ANY) { 402 return true; 403 } 404 else if (dep.getComparison() == Dependency.COMPARE_SPEC) { 405 if (otherModule.getSpecificationVersion() == null) 406 return false; 407 else if (new SpecificationVersion(dep.getVersion()).compareTo(otherModule.getSpecificationVersion()) > 0) 408 return false; 409 else 410 return true; 411 } 412 else { 413 if (otherModule.getImplementationVersion () == null) 415 return false; 416 else if (! otherModule.getImplementationVersion ().equals (dep.getVersion())) 417 return false; 418 else 419 return true; 420 } 421 } 422 423 int dash = depName.indexOf('-'); if (dash != -1) { 425 int slash = depName.indexOf('/'); String cnb = depName.substring(0, slash); 428 int relMin = Integer.parseInt(depName.substring(slash + 1, dash)); 429 int relMax = Integer.parseInt(depName.substring(dash + 1)); 430 if (cnb.equals(otherModule.getCodeNameBase()) && 431 relMin <= otherModule.getCodeNameRelease() && 432 relMax >= otherModule.getCodeNameRelease()) { 433 if (dep.getComparison() == Dependency.COMPARE_ANY) { 434 return true; 435 } else { 436 if (otherModule.getCodeNameRelease() > relMin) { 438 return true; 440 } else { 441 if (otherModule.getSpecificationVersion() == null) 443 return false; 444 else if (new SpecificationVersion(dep.getVersion()).compareTo(otherModule.getSpecificationVersion()) > 0) 445 return false; 446 else 447 return true; 448 } 449 } 450 } 451 } 452 453 return false; 454 } 455 456 457 458 boolean checkIdeDependency( Dependency dep, 459 ModuleInfo ide ) { 460 461 String IDEName = ide.getCodeName(); 462 SpecificationVersion IDESpecVersion = ide.getSpecificationVersion(); 463 String IDEImplVersion = ide.getImplementationVersion(); 464 465 if ( !IDEName.equals ( dep.getName() ) ) 467 return false; 468 470 if ( dep.getComparison() == Dependency.COMPARE_SPEC ) { 471 return new SpecificationVersion(dep.getVersion()).compareTo(IDESpecVersion) <= 0; 472 } 474 else if ( dep.getComparison() == Dependency.COMPARE_IMPL ) { 475 return dep.getVersion().equals (IDEImplVersion); 476 } 478 else { 479 throw new IllegalStateException ("Cannot have COMPARE_ANY on IDE dependency"); } 482 } 483 484 private List checkBrokenImplDependency( ModuleInfo md, Collection result ) { 485 ModuleInfo[] installedModules = Updates.getInstalledModules(); 486 487 List brokenlist = new ArrayList(); 488 Dependency dep, depR; 489 for (int i = 0; i < installedModules.length; i++) { 490 Iterator deps = installedModules[i].getDependencies().iterator(); 491 while ( deps.hasNext() ) { 492 dep = (Dependency) deps.next(); 493 if ( dep.getName().equals (md.getCodeName ()) 494 && dep.getComparison() == Dependency.COMPARE_IMPL ) { 495 if ( ! dep.getVersion().equals( md.getImplementationVersion() ) ) { 496 Iterator it = Wizard.getAllModules().iterator(); 499 boolean found = false; 500 while ( it.hasNext() ) { 501 ModuleUpdate mu = (ModuleUpdate)it.next(); 502 if ( mu.getRemoteModule().getCodeName().equals( installedModules[i].getCodeName() ) 503 && mu.getRemoteModule().getSpecificationVersion().compareTo( 504 installedModules[i].getSpecificationVersion() ) > 0 ) 505 { 506 boolean maybeOK = true; 507 Iterator depsR = mu.getRemoteModule().getDependencies().iterator(); 508 while ( depsR.hasNext() ) { 509 depR = (Dependency) depsR.next(); 510 if ( depR.getName().equals (md.getCodeName ()) 511 && depR.getComparison() == Dependency.COMPARE_IMPL 512 && !depR.getVersion().equals( md.getImplementationVersion() ) ) 513 { 514 maybeOK = false; 515 break; 516 } 517 } 518 if ( maybeOK ) { 519 if ( !result.contains( mu ) ) { 520 result.add( mu ); 521 } 522 found = true; 523 break; 524 } 525 } 526 } 527 if ( !found ) { 528 brokenlist.add( installedModules[i] ); 529 } 530 break; 531 } 532 break; 533 } 534 } 535 } 536 537 return brokenlist; 538 } 539 540 static boolean checkPlatformDependency (ModuleInfo module) { 541 Set deps = module.getDependencies (); 542 Iterator it = deps.iterator (); 543 boolean res = true; 545 while (it.hasNext ()) { 546 Dependency d = (Dependency) it.next (); 547 if (Dependency.TYPE_REQUIRES == d.getType ()) { 548 if (d.getName ().startsWith ("org.openide.modules.os")) { res = false; 551 ModuleInfo[] installedModules = Updates.getInstalledModules (); 552 for (int i = 0; ! res && (i < installedModules.length); i++) { 553 res = checkModuleDependency (d, installedModules [i]); 554 } 555 err.log(Level.FINE, 556 "checkPlatformDependency on module " + 557 module.getCodeNameBase() + " which requires " + d + 558 " returns " + res); 559 } 560 } 561 } 562 return res; 564 } 565 566 private static boolean checkFreeLocalizationDependency (ModuleUpdate baseModule, String locale, Collection result, Enumeration selected, List group) { 567 boolean ok = false; 568 569 if (baseModule instanceof L10NUpdate) { 570 return false; 572 } 573 574 if (selected != null) { 575 576 while ( selected.hasMoreElements() ) { 577 ModuleUpdate mu = (ModuleUpdate) selected.nextElement (); 578 if (mu instanceof L10NUpdate) { 579 L10NUpdate lu = (L10NUpdate) mu; 580 581 ok = locale.equals (lu.getLangcode ()) && lu.getCodeNameBase ().equals (baseModule.getCodeNameBase ()); 582 583 if ( ok ) { 584 if ( !result.contains (lu) ) { 585 err.log(Level.FINE, 586 " ADDED[SELECTED]: " + lu.getCodeNameBase() + 587 "[" + lu.getLangcode() + "]"); 588 result.add (lu); 589 } 590 break; 591 } 592 } 593 } 594 } 595 596 if ( !ok && group != null ) { 597 Iterator it = group.iterator(); 598 while ( it.hasNext() ) { 599 ModuleUpdate mu = (ModuleUpdate)it.next(); 600 if (mu instanceof L10NUpdate) { 601 L10NUpdate lu = (L10NUpdate) mu; 602 603 ok = locale.equals (lu.getLangcode ()) && lu.getCodeNameBase ().equals (baseModule.getCodeNameBase ()); 604 605 if ( ok ) { 606 if ( !result.contains (lu) ) { 607 err.log(Level.FINE, 608 " ADDED[GROUP]: " + lu.getCodeNameBase() + 609 "[" + lu.getLangcode() + "]"); 610 result.add (lu); 611 } 612 break; 613 } 614 } 615 } 616 } 617 618 if ( !ok ) { 619 620 Iterator it = Wizard.getAllModules().iterator(); 621 while ( it.hasNext() ) { 622 ModuleUpdate mu = (ModuleUpdate)it.next(); 623 if (mu instanceof L10NUpdate) { 624 L10NUpdate lu = (L10NUpdate) mu; 625 626 ok = locale.equals (lu.getLangcode ()) && lu.getCodeNameBase ().equals (baseModule.getCodeNameBase ()); 627 628 if ( ok ) { 629 if ( !result.contains (lu) ) { 630 err.log(Level.FINE, 631 " ADDED[ALL]: " + lu.getCodeNameBase() + 632 "[" + lu.getLangcode() + "]"); 633 result.add (lu); 634 } 635 break; 636 } 637 } 638 } 639 } 640 641 return ok; 642 } 643 644 private String getBundle( String key ) { 645 return NbBundle.getMessage( DependencyChecker.class, key ); 646 } 647 648 } 684 | Popular Tags |