1 19 20 package org.netbeans.nbbuild; 21 22 import java.io.*; 23 import java.io.IOException ; 24 import java.util.*; 25 import java.util.jar.JarEntry ; 26 import java.util.jar.JarFile ; 27 import org.apache.tools.ant.BuildException; 28 29 35 public class ModuleDependencies extends org.apache.tools.ant.Task { 36 private List<Input> inputs = new ArrayList<Input>(); 37 private List<Output> outputs = new ArrayList<Output>(); 38 private Set<ModuleInfo> modules; 39 private Set<File > external; 40 41 public ModuleDependencies () { 42 } 43 44 public Input createInput () throws org.apache.tools.ant.BuildException { 45 Input input = new Input (); 46 inputs.add (input); 47 return input; 48 } 49 50 public Output createOutput () throws org.apache.tools.ant.BuildException { 51 Output output = new Output (); 52 outputs.add (output); 53 return output; 54 } 55 56 public void execute () throws BuildException { 57 if (outputs.size () == 0) throw new BuildException ("At least one <output> tag has to be specified"); 58 59 try { 60 readModuleInfo (); 61 62 Iterator it = outputs.iterator (); 63 while (it.hasNext ()) { 64 Output o = (Output)it.next (); 65 if (o.type == null) throw new BuildException ("<output> needs attribute type"); 66 if (o.file == null) throw new BuildException ("<output> needs attribute file"); 67 68 getProject ().log ("Generating " + o.type + " to " + o.file); 69 70 if ("public-packages".equals (o.type.getValue ())) { 71 generatePublicPackages (o.file, true, false); 72 continue; 73 } 74 if ("friend-packages".equals (o.type.getValue ())) { 75 generatePublicPackages (o.file, false, false); 76 continue; 77 } 78 if ("shared-packages".equals (o.type.getValue ())) { 79 generateSharedPackages (o.file); 80 continue; 81 } 82 if ("modules".equals (o.type.getValue ())) { 83 generateListOfModules (o.file); 84 continue; 85 } 86 if ("dependencies".equals (o.type.getValue ())) { 87 generateDependencies (o.file, false); 88 continue; 89 } 90 if ("implementation-dependencies".equals (o.type.getValue ())) { 91 generateDependencies (o.file, true); 92 continue; 93 } 94 if ("group-dependencies".equals (o.type.getValue ())) { 95 generateGroupDependencies (o.file, false); 96 continue; 97 } 98 if ("group-implementation-dependencies".equals (o.type.getValue ())) { 99 generateGroupDependencies (o.file, true); 100 continue; 101 } 102 if ("group-friend-packages".equals (o.type.getValue ())) { 103 generatePublicPackages(o.file, false, true); 104 continue; 105 } 106 if ("external-libraries".equals (o.type.getValue ())) { 107 generateExternalLibraries (o.file); 108 continue; 109 } 110 } 111 112 } catch (IOException ex) { 113 throw new BuildException (ex); 114 } 115 } 116 117 private void readModuleInfo () throws IOException { 118 modules = new TreeSet<ModuleInfo>(); 119 120 class Comp implements java.util.Comparator <File > { 121 public int compare (File f1, File f2) { 122 return f1.getName ().compareTo (f2.getName ()); 123 } 124 } 125 external = new TreeSet<File >(new Comp ()); 126 127 Iterator<Input> it = inputs.iterator (); 128 if (!it.hasNext ()) throw new BuildException ("At least one <input> tag is needed"); 129 while (it.hasNext ()) { 130 Input input = it.next (); 131 if (input.jars == null) throw new BuildException ("<input> needs a subelement <jars>"); 132 if (input.name == null) throw new BuildException ("<input> needs attribute name"); 133 134 org.apache.tools.ant.Project p = getProject (); 135 org.apache.tools.ant.DirectoryScanner scan = input.jars.getDirectoryScanner (p); 136 String [] arr = scan.getIncludedFiles (); 137 for (int i = 0; i < arr.length; i++) { 138 File f = new File (scan.getBasedir (), arr[i]); 139 getProject ().log ("Processing " + f, getProject ().MSG_VERBOSE); 140 JarFile file = new JarFile (f); 141 142 java.util.jar.Manifest manifest = file.getManifest (); 143 if (manifest == null) { 144 external.add (f); 146 continue; 147 } 148 149 String module = manifest.getMainAttributes ().getValue ("OpenIDE-Module"); 150 151 152 if (module == null) { 153 if (manifest.getMainAttributes ().getValue ("NetBeans-Own-Library") == null) { 155 external.add (f); 156 } 157 continue; 158 } 159 160 161 ModuleInfo m; 162 { 163 String codebasename; 164 int majorVersion; 165 int slash = module.indexOf ('/'); 167 if (slash == -1) { 168 codebasename = module; 169 majorVersion = -1; 170 } else { 171 codebasename = module.substring (0, slash); 172 majorVersion = Integer.valueOf (module.substring (slash + 1)).intValue (); 173 } 174 m = new ModuleInfo (input.name, f, codebasename); 175 m.majorVersion = majorVersion; 176 } 177 178 m.publicPackages = file.getManifest ().getMainAttributes ().getValue ("OpenIDE-Module-Public-Packages"); 179 180 { 181 m.specificationVersion = file.getManifest ().getMainAttributes ().getValue ("OpenIDE-Module-Specification-Version"); 182 } 183 184 m.implementationVersion = file.getManifest ().getMainAttributes ().getValue ("OpenIDE-Module-Implementation-Version"); 185 186 TreeSet<Dependency> depends = new TreeSet<Dependency>(); 187 TreeSet<Dependency> provides = new TreeSet<Dependency>(); 188 addDependencies (depends, file.getManifest (), Dependency.REQUIRES, "OpenIDE-Module-Requires"); 189 addDependencies (provides, file.getManifest (), Dependency.PROVIDES, "OpenIDE-Module-Provides"); 190 { 191 String ideDeps = file.getManifest ().getMainAttributes ().getValue ("OpenIDE-Module-IDE-Dependencies"); if (ideDeps != null) { 193 StringTokenizer tok = new StringTokenizer (ideDeps, "> "); 194 if (tok.countTokens () != 2 || !tok.nextToken ().equals ("IDE/1")) { 195 throw new BuildException ("Wrong OpenIDE-Module-IDE-Dependencies: " + ideDeps); 196 } 197 } 198 } 199 addDependencies (depends, file.getManifest (), Dependency.REQUIRES, "OpenIDE-Module-Module-Dependencies"); 200 206 m.depends = depends; 207 m.provides = provides; 208 { 209 String friends = file.getManifest ().getMainAttributes ().getValue ("OpenIDE-Module-Friends"); 210 if (friends != null) { 211 TreeSet<String > set = new TreeSet<String >(); 212 StringTokenizer tok = new StringTokenizer(friends, ", "); 213 while (tok.hasMoreElements()) { 214 set.add(tok.nextToken()); 215 } 216 m.friends = set; 217 } 218 } 219 220 modules.add (m); 221 } 222 } 223 } 224 225 226 private void generatePublicPackages(File output, boolean justPublic, boolean justInterCluster) throws BuildException, IOException { 227 TreeSet<String > packages = new TreeSet<String >(); 228 TreeMap<ModuleInfo,TreeSet<String >> friendExports = new TreeMap<ModuleInfo,TreeSet<String >>(); 229 230 { 231 for (ModuleInfo m : modules) { 232 if (justPublic) { 233 if (m.friends != null) { 234 continue; 235 } 236 } 237 238 String s = m.publicPackages; 239 HashMap<String ,Boolean > pkgs = null; 240 if (s != null) { 241 pkgs = new HashMap<String ,Boolean >(); 242 StringTokenizer tok = new StringTokenizer(s, ","); 243 while (tok.hasMoreElements()) { 244 String p = tok.nextToken().trim(); 245 if (p.equals("-")) { 246 continue; 247 } 248 249 if (p.endsWith(".*")) { 250 pkgs.put(p.substring(0, p.length() - 2).replace('.', '/'), Boolean.FALSE); 251 continue; 252 } 253 if (p.endsWith(".**")) { 254 pkgs.put(p.substring(0, p.length() - 3).replace('.', '/'), Boolean.TRUE); 255 continue; 256 } 257 throw new BuildException("Unknown package format: " + p + " in " + m.file); 258 } 259 } 260 261 if (justPublic) { 262 iterateThruPackages(m.file, pkgs, packages); 263 if (pkgs != null && packages.size() < pkgs.size()) { 264 throw new BuildException("Not enough packages found. The declared packages are: " + s + " but only " + packages + " were found in " + m.file); 265 } 266 } else { 267 TreeSet<String > modulePkgs = new TreeSet<String >(); 268 iterateThruPackages(m.file, pkgs, modulePkgs); 269 friendExports.put(m, modulePkgs); 270 } 271 272 } 273 } 274 275 PrintWriter w = new PrintWriter(new FileWriter(output)); 276 if (justPublic) { 277 Iterator it = packages.iterator(); 278 while (it.hasNext()) { 279 String out = (String )it.next(); 280 w.println(out.replace('/', '.')); 281 } 282 } else { 283 int maxFriends = Integer.MAX_VALUE; 284 if (justInterCluster) { 285 String maxFriendsString = this.getProject().getProperty("deps.max.friends"); 286 if (maxFriendsString != null) { 287 maxFriends = Integer.parseInt(maxFriendsString); 288 } 289 } 290 291 Iterator<Map.Entry<ModuleInfo,TreeSet<String >>> it = friendExports.entrySet().iterator(); 292 while (it.hasNext()) { 293 Map.Entry<ModuleInfo,TreeSet<String >> entry = it.next(); 294 ModuleInfo info = entry.getKey(); 295 if (info.friends == null) { 296 continue; 297 } 298 log("Friends for " + info.getName(), org.apache.tools.ant.Project.MSG_DEBUG); 299 Iterator iterFrnd = info.friends.iterator(); 300 int cntFriends = 0; 301 boolean printed = false; 302 while(iterFrnd.hasNext()) { 303 String n = (String )iterFrnd.next(); 304 ModuleInfo friend = findModuleInfo(n); 305 if (justInterCluster && friend != null && friend.group.equals(info.group)) { 306 continue; 307 } 308 309 if (!printed) { 310 w.print("MODULE "); 311 w.println(info.getName()); 312 printed = true; 313 } 314 315 if (friend != null) { 316 w.print(" FRIEND "); 317 w.println(friend.getName()); 318 } else { 319 w.print(" EXTERNAL "); 320 w.println(n); 321 } 322 cntFriends++; 323 } 324 if (cntFriends > maxFriends) { 325 throw new BuildException("Too many intercluster friends (" + cntFriends + ") for module " + info.getName()); 326 } 327 328 if (cntFriends > 0) { 329 Set<String > pkgs = entry.getValue(); 330 Iterator iterPkgs = pkgs.iterator(); 331 while (iterPkgs.hasNext()) { 332 String out = (String )iterPkgs.next(); 333 w.print(" PACKAGE "); 334 w.println(out.replace('/', '.')); 335 } 336 } 337 } 338 } 339 w.close(); 340 } 341 342 private void iterateThruPackages (File f, HashMap pkgs, TreeSet<String > packages) throws IOException { 343 JarFile file = new JarFile (f); 344 Enumeration en = file.entries (); 345 LOOP: while (en.hasMoreElements ()) { 346 JarEntry e = (JarEntry )en.nextElement (); 347 if (e.getName ().endsWith (".class")) { 348 int last = e.getName ().lastIndexOf ('/'); 349 if (last == -1) { 350 continue; 352 } 353 String p = e.getName ().substring (0, last); 354 355 if (pkgs == null) { 356 packages.add (p); 357 continue; 358 } 359 360 Boolean b = (Boolean )pkgs.get (p); 361 if (b != null) { 362 packages.add (p); 363 continue; 364 } 365 366 String parent = p; 367 while (parent.length () > 0) { 368 int prev = parent.lastIndexOf ('/'); 369 if (prev == -1) { 370 parent = ""; 371 } else { 372 parent = parent.substring (0, prev); 373 } 374 375 b = (Boolean )pkgs.get (parent); 376 if (Boolean.TRUE.equals (b)) { 377 packages.add (p); 378 continue LOOP; 379 } 380 } 381 } 382 } 383 384 java.util.jar.Manifest m = file.getManifest (); 385 if (m != null) { 386 String value = m.getMainAttributes ().getValue ("Class-Path"); 387 if (value != null) { 388 StringTokenizer tok = new StringTokenizer (value, " "); 389 while (tok.hasMoreElements ()) { 390 File sub = new File (f.getParentFile (), tok.nextToken ()); 391 if (sub.isFile ()) { 392 iterateThruPackages (sub, pkgs, packages); 393 } 394 } 395 } 396 } 397 398 file.close (); 399 } 400 401 private void generateListOfModules (File output) throws BuildException, IOException { 402 PrintWriter w = new PrintWriter (new FileWriter (output)); 403 Iterator it = modules.iterator (); 404 while (it.hasNext ()) { 405 ModuleInfo m = (ModuleInfo)it.next (); 406 w.print ("MODULE "); 407 w.print (m.getName ()); 408 w.println (); 409 } 410 w.close (); 411 } 412 413 private void generateExternalLibraries (File output) throws BuildException, IOException { 414 PrintWriter w = new PrintWriter (new FileWriter (output)); 415 Iterator it = external.iterator (); 416 417 String SPACES = " "; 418 while (it.hasNext ()) { 419 File f = (File )it.next (); 420 421 java.security.MessageDigest dig; 422 423 try { 424 dig = java.security.MessageDigest.getInstance ("MD5"); 425 } catch (java.security.NoSuchAlgorithmException ex) { 426 throw new BuildException (ex); 427 } 428 InputStream is = new BufferedInputStream (new FileInputStream (f)); 429 byte[] arr = new byte[4092]; 430 for (;;) { 431 int len = is.read (arr); 432 if (len == -1) { 433 break; 434 } 435 dig.update (arr, 0, len); 436 } 437 438 byte[] res = dig.digest (); 439 is.close (); 440 441 w.print ("LIBRARY "); 442 w.print ((f.getName () + SPACES).substring (0, 50)); 443 String size = SPACES + f.length (); 444 w.print (size.substring (size.length () - 15)); 445 w.print (" "); 446 for (int i = 0; i < res.length; i++) { 447 String hex = "00" + Integer.toHexString (res[i]); 448 w.print (hex.substring (hex.length () - 2)); 449 } 450 w.println (); 451 } 452 w.close (); 453 } 454 455 private void generateSharedPackages (File output) throws BuildException, IOException { 456 TreeMap<String ,List<ModuleInfo>> packages = new TreeMap<String ,List<ModuleInfo>>(); 457 458 { 459 Iterator<ModuleInfo> it = modules.iterator (); 460 while (it.hasNext ()) { 461 ModuleInfo m = it.next (); 462 463 HashSet<String > pkgs = new HashSet<String >(); 464 iterateSharedPackages (m.file, pkgs); 465 466 Iterator j = pkgs.iterator (); 467 while (j.hasNext ()) { 468 String s = (String )j.next (); 469 List<ModuleInfo> l = packages.get(s); 470 if (l == null) { 471 l = new ArrayList<ModuleInfo>(); 472 packages.put(s, l); 473 } 474 l.add (m); 475 } 476 } 477 } 478 479 PrintWriter w = new PrintWriter (new FileWriter (output)); 480 Iterator it = packages.entrySet ().iterator (); 481 while (it.hasNext ()) { 482 Map.Entry entry = (Map.Entry)it.next (); 483 String out = (String )entry.getKey (); 484 List cnt = (List)entry.getValue (); 485 if (cnt.size() > 1) { 486 w.println (out.replace ('/', '.')); 487 log("Package " + out + " is shared between:", org.apache.tools.ant.Project.MSG_VERBOSE); 488 Iterator j = cnt.iterator (); 489 while (j.hasNext ()) { 490 ModuleInfo m = (ModuleInfo)j.next (); 491 log (" " + m.codebasename, org.apache.tools.ant.Project.MSG_VERBOSE); 492 } 493 } 494 } 495 w.close (); 496 } 497 498 private void iterateSharedPackages (File f, Set<String > myPkgs) throws IOException { 499 JarFile file = new JarFile (f); 500 Enumeration<JarEntry > en = file.entries (); 501 LOOP: while (en.hasMoreElements ()) { 502 JarEntry e = en.nextElement (); 503 if (e.getName ().endsWith ("/")) { 504 continue; 505 } 506 if (e.getName ().startsWith ("META-INF/")) { 507 continue; 508 } 509 510 int last = e.getName ().lastIndexOf ('/'); 511 String pkg = last == -1 ? "" : e.getName ().substring (0, last); 512 myPkgs.add (pkg); 513 log("Found package " + pkg + " in " + f, getProject().MSG_DEBUG); 514 } 515 516 java.util.jar.Manifest m = file.getManifest (); 517 if (m != null) { 518 String value = m.getMainAttributes ().getValue ("Class-Path"); 519 if (value != null) { 520 StringTokenizer tok = new StringTokenizer (value, " "); 521 while (tok.hasMoreElements ()) { 522 File sub = new File (f.getParentFile (), tok.nextToken ()); 523 if (sub.isFile ()) { 524 iterateSharedPackages (sub, myPkgs); 525 } 526 } 527 } 528 } 529 530 file.close (); 531 } 532 533 private void generateDependencies (File output, boolean implementationOnly) throws BuildException, IOException { 534 PrintWriter w = new PrintWriter (new FileWriter (output)); 535 Iterator it = modules.iterator (); 536 while (it.hasNext ()) { 537 ModuleInfo m = (ModuleInfo)it.next (); 538 539 boolean first = true; 540 Iterator deps = m.depends.iterator (); 541 while (deps.hasNext ()) { 542 Dependency d = (Dependency)deps.next (); 543 String print = " REQUIRES "; 544 if (d.exact && d.compare != null) { 545 } else { 547 if (implementationOnly) { 548 continue; 549 } 550 } 551 if (first) { 552 w.print ("MODULE "); 553 w.print (m.getName ()); 554 w.println (); 555 first = false; 556 } 557 w.print (print); 558 if (d.isSpecial ()) { 559 w.print (d.getName ()); 560 } else { 561 ModuleInfo theModuleOneIsDependingOn = findModuleInfo (d); 562 w.print (theModuleOneIsDependingOn.getName ()); 563 } 564 w.println (); 565 } 566 } 567 w.close (); 568 } 569 570 private void generateGroupDependencies (File output, boolean implementationOnly) throws BuildException, IOException { 571 PrintWriter w = new PrintWriter (new FileWriter (output)); 572 573 TreeMap<String , Set<Dependency>> groups = new TreeMap<String , Set<Dependency>>(); 574 { 575 Iterator<ModuleInfo> it = modules.iterator (); 576 577 while (it.hasNext ()) { 578 ModuleInfo m = it.next (); 579 Set<Dependency> l = groups.get (m.group); 580 if (l == null) { 581 l = new TreeSet<Dependency>(); 582 groups.put (m.group, l); 583 } 584 585 l.addAll(m.depends); 586 } 587 } 588 589 Iterator it = groups.entrySet ().iterator (); 590 while (it.hasNext ()) { 591 Map.Entry e = (Map.Entry)it.next (); 592 String groupName = (String )e.getKey (); 593 Set depends = (Set)e.getValue (); 594 595 boolean first = true; 596 Iterator deps = depends.iterator (); 597 while (deps.hasNext ()) { 598 Dependency d = (Dependency)deps.next (); 599 600 String print = " REQUIRES "; 601 if (d.exact && d.compare != null) { 602 } else { 604 if (implementationOnly) { 605 continue; 606 } 607 } 608 609 if (d.isSpecial ()) { 611 continue; 612 } 613 ModuleInfo ref = findModuleInfo (d); 615 if (groupName.equals (ref.group)) { 616 continue; 617 } 618 619 if (first) { 620 w.print ("GROUP "); 621 w.print (groupName); 622 w.println (); 623 first = false; 624 } 625 w.print (print); 626 w.print (ref.getName ()); 627 w.println (); 628 } 629 } 630 w.close (); 631 } 632 633 635 private ModuleInfo findModuleInfo (Dependency dep) throws BuildException { 636 Iterator it = modules.iterator (); 637 while (it.hasNext ()) { 638 ModuleInfo info = (ModuleInfo)it.next (); 639 if (dep.isDependingOn (info)) { 640 return info; 641 } 642 } 643 644 throw new BuildException ("Cannot find module that satisfies dependency: " + dep); 645 } 646 648 private ModuleInfo findModuleInfo (String cnb) throws BuildException { 649 Iterator it = modules.iterator (); 650 while (it.hasNext ()) { 651 ModuleInfo info = (ModuleInfo)it.next (); 652 if (info.codebasename.equals(cnb)) { 653 return info; 654 } 655 } 656 657 return null; 658 } 659 660 private static void addDependencies (TreeSet<Dependency> addTo, java.util.jar.Manifest man, int dependencyType, String attrName) throws BuildException { 661 String value = man.getMainAttributes ().getValue (attrName); 662 if (value == null) { 663 return; 664 } 665 666 StringTokenizer tok = new StringTokenizer (value, ","); 667 while (tok.hasMoreElements ()) { 668 String nextDep = tok.nextToken (); 669 StringTokenizer dep = new StringTokenizer (nextDep, "=>", true); 670 if (dep.countTokens () == 1) { 671 addTo.add (new Dependency (dep.nextToken ().trim (), dependencyType, false, null)); 672 continue; 673 } 674 675 if (dep.countTokens () == 3) { 676 String name = dep.nextToken ().trim (); 677 String equal = dep.nextToken ().trim (); 678 String comp = dep.nextToken ().trim (); 679 addTo.add (new Dependency (name, dependencyType, equal.equals ("="), comp)); 680 continue; 681 } 682 683 throw new BuildException ("Cannot parse dependency: " + value); 684 } 685 } 686 687 public static final class Input extends Object { 688 public org.apache.tools.ant.types.FileSet jars; 689 public String name; 690 691 public org.apache.tools.ant.types.FileSet createJars () { 692 if (jars != null) throw new BuildException (); 693 jars = new org.apache.tools.ant.types.FileSet (); 694 return jars; 695 } 696 697 public void setName (String name) { 698 this.name = name; 699 } 700 } 701 702 public static final class Output extends Object { 703 public OutputType type; 704 public java.io.File file; 705 706 public void setType (OutputType type) { 707 this.type = type; 708 } 709 710 public void setFile (File file) { 711 this.file = file; 712 } 713 } 714 715 public static final class OutputType extends org.apache.tools.ant.types.EnumeratedAttribute { 716 public String [] getValues () { 717 return new String [] { 718 "public-packages", 719 "friend-packages", 720 "shared-packages", 721 "modules", 722 "dependencies", 723 "implementation-dependencies", 724 "group-dependencies", 725 "group-implementation-dependencies", 726 "group-friend-packages", 727 "external-libraries", 728 }; 729 } 730 } 731 732 private static final class ModuleInfo extends Object implements Comparable { 733 public final String group; 734 public final File file; 735 public final String codebasename; 736 public String publicPackages; 737 public Set friends; 738 public int majorVersion; 739 public String specificationVersion; 740 public String implementationVersion; 741 public Set<Dependency> depends; 742 public Set<Dependency> provides; 743 744 public ModuleInfo (String g, File f, String a) { 745 this.group = g; 746 this.file = f; 747 this.codebasename = a; 748 } 749 750 public int compareTo (Object o) { 751 ModuleInfo m = (ModuleInfo)o; 752 return codebasename.compareTo (m.codebasename); 753 } 754 755 public boolean equals (Object obj) { 756 if (obj instanceof ModuleInfo) { 757 return compareTo (obj) == 0; 758 } 759 return false; 760 } 761 762 public int hashCode () { 763 return codebasename.hashCode (); 764 } 765 766 public String getName () { 767 if (majorVersion == -1) { 768 return codebasename + " (" + group + ")"; 769 } else { 770 return codebasename + "/" + majorVersion + " (" + group + ")"; 771 } 772 } 773 774 public String toString () { 775 return "ModuleInfo[" + getName () + "]"; 776 } 777 } 779 private static final class Dependency extends Object implements Comparable { 780 public static final int PROVIDES = 1; 781 public static final int REQUIRES = 2; 782 783 public final String token; 784 public final int majorVersionFrom; 785 public final int majorVersionTo; 786 public final int type; 787 public final boolean exact; 788 public final String compare; 789 790 791 public Dependency (String token, int type, boolean exact, String compare) { 792 int slash = token.indexOf ('/'); 794 if (slash == -1) { 795 this.token = token; 796 this.majorVersionFrom = -1; 797 this.majorVersionTo = -1; 798 } else { 799 this.token = token.substring (0, slash); 800 801 String major = token.substring (slash + 1); 802 int range = major.indexOf ('-'); 803 if (range == -1) { 804 this.majorVersionFrom = Integer.valueOf (major).intValue (); 805 this.majorVersionTo = majorVersionFrom; 806 } else { 807 this.majorVersionFrom = Integer.valueOf (major.substring (0, range)).intValue (); 808 this.majorVersionTo = Integer.valueOf (major.substring (range + 1)).intValue (); 809 } 810 } 811 this.type = type; 812 this.exact = exact; 813 this.compare = compare; 814 } 815 public int compareTo (Object o) { 816 Dependency m = (Dependency)o; 817 return token.compareTo (m.token); 818 } 819 820 public boolean equals (Object obj) { 821 if (obj instanceof Dependency) { 822 return compareTo (obj) == 0; 823 } 824 return false; 825 } 826 827 public int hashCode () { 828 return token.hashCode (); 829 } 830 831 834 public boolean isSpecial () { 835 return token.startsWith ("org.openide.modules.os") || 836 token.startsWith ("org.openide.modules.ModuleFormat"); 837 } 838 839 public boolean isDependingOn (ModuleInfo info) { 840 if (info.codebasename.equals (token)) { 841 return majorVersionTo <= info.majorVersion && majorVersionFrom <= info.majorVersion; 842 } 843 844 Iterator it = info.provides.iterator (); 845 while (it.hasNext ()) { 846 Dependency d = (Dependency)it.next (); 847 if (d.equals (this)) { 848 return true; 849 } 850 } 851 852 return false; 853 } 854 855 public String getName () { 856 if (majorVersionFrom == -1 && majorVersionTo == -1) { 857 return token; 858 } else { 859 if (majorVersionTo == majorVersionFrom) { 860 return token + "/" + majorVersionFrom; 861 } else { 862 return token + "/" + majorVersionFrom + "-" + majorVersionTo; 863 } 864 } 865 866 } 867 868 public String toString () { 869 String t; 870 switch (type) { 871 case REQUIRES: t = "requires "; break; 872 case PROVIDES: t = "provides "; break; 873 default: 874 throw new IllegalStateException ("Unknown type: " + type); 875 } 876 877 return "Dependency[" + t + getName () + "]"; 878 } 879 880 } } 882 | Popular Tags |