KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > nbbuild > ModuleDependencies


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.nbbuild;
21
22 import java.io.*;
23 import java.io.IOException JavaDoc;
24 import java.util.*;
25 import java.util.jar.JarEntry JavaDoc;
26 import java.util.jar.JarFile JavaDoc;
27 import org.apache.tools.ant.BuildException;
28
29 /** This task implements the module dependencies verification proposal
30  * that is described at
31  * http://openide.netbeans.org/proposals/arch/clusters.html#verify-solution
32  *
33  *
34  */

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 JavaDoc> 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 JavaDoc ex) {
113             throw new BuildException (ex);
114         }
115     }
116     
117     private void readModuleInfo () throws IOException JavaDoc {
118         modules = new TreeSet<ModuleInfo>();
119         
120         class Comp implements java.util.Comparator JavaDoc<File JavaDoc> {
121             public int compare (File JavaDoc f1, File JavaDoc f2) {
122                 return f1.getName ().compareTo (f2.getName ());
123             }
124         }
125         external = new TreeSet<File JavaDoc>(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 JavaDoc[] arr = scan.getIncludedFiles ();
137             for (int i = 0; i < arr.length; i++) {
138                 File JavaDoc f = new File JavaDoc (scan.getBasedir (), arr[i]);
139                 getProject ().log ("Processing " + f, getProject ().MSG_VERBOSE);
140                 JarFile JavaDoc file = new JarFile JavaDoc (f);
141                 
142                 java.util.jar.Manifest JavaDoc manifest = file.getManifest ();
143                 if (manifest == null) {
144                     // process only manifest files
145
external.add (f);
146                     continue;
147                 }
148                 
149                 String JavaDoc module = manifest.getMainAttributes ().getValue ("OpenIDE-Module");
150                 
151                 
152                 if (module == null) {
153                     // skip this one
154
if (manifest.getMainAttributes ().getValue ("NetBeans-Own-Library") == null) {
155                         external.add (f);
156                     }
157                     continue;
158                 }
159
160
161                 ModuleInfo m;
162                 {
163                     String JavaDoc codebasename;
164                     int majorVersion;
165                     // base name
166
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 JavaDoc ideDeps = file.getManifest ().getMainAttributes ().getValue ("OpenIDE-Module-IDE-Dependencies"); // IDE/1 > 4.25
192
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                 /* org.netbeans.api.java/1,org.netbeans.modules.queries/0,
201                  org.netbeans.modules.javacore/1,org.netbeans.jmi.javamodel/1 > 1.11,org.netbeans.api.mdr/1,
202                  org.netbeans.modules.mdr/1= 1.0.0,org.netbeans.modules.
203                  jmiutils/1 = 1.0.0,javax.jmi.reflect/1,
204                  org.openide.loaders,org.openide.src > 1.0
205                  */

206                 m.depends = depends;
207                 m.provides = provides;
208                 {
209                     String JavaDoc friends = file.getManifest ().getMainAttributes ().getValue ("OpenIDE-Module-Friends");
210                     if (friends != null) {
211             TreeSet<String JavaDoc> set = new TreeSet<String JavaDoc>();
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 JavaDoc output, boolean justPublic, boolean justInterCluster) throws BuildException, IOException JavaDoc {
227         TreeSet<String JavaDoc> packages = new TreeSet<String JavaDoc>();
228         TreeMap<ModuleInfo,TreeSet<String JavaDoc>> friendExports = new TreeMap<ModuleInfo,TreeSet<String JavaDoc>>();
229         
230         {
231             for (ModuleInfo m : modules) {
232                 if (justPublic) {
233                     if (m.friends != null) {
234                         continue;
235                     }
236                 }
237
238                 String JavaDoc s = m.publicPackages;
239                 HashMap<String JavaDoc,Boolean JavaDoc> pkgs = null;
240                 if (s != null) {
241                     pkgs = new HashMap<String JavaDoc,Boolean JavaDoc>();
242                     StringTokenizer tok = new StringTokenizer(s, ",");
243                     while (tok.hasMoreElements()) {
244                         String JavaDoc 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 JavaDoc> modulePkgs = new TreeSet<String JavaDoc>();
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 JavaDoc out = (String JavaDoc)it.next();
280                 w.println(out.replace('/', '.'));
281             }
282         } else {
283             int maxFriends = Integer.MAX_VALUE;
284             if (justInterCluster) {
285                 String JavaDoc 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 JavaDoc>>> it = friendExports.entrySet().iterator();
292             while (it.hasNext()) {
293                 Map.Entry<ModuleInfo,TreeSet<String JavaDoc>> 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 JavaDoc n = (String JavaDoc)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 JavaDoc> pkgs = entry.getValue();
330                     Iterator iterPkgs = pkgs.iterator();
331                     while (iterPkgs.hasNext()) {
332                         String JavaDoc out = (String JavaDoc)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 JavaDoc f, HashMap pkgs, TreeSet<String JavaDoc> packages) throws IOException JavaDoc {
343         JarFile JavaDoc file = new JarFile JavaDoc (f);
344         Enumeration en = file.entries ();
345         LOOP: while (en.hasMoreElements ()) {
346             JarEntry JavaDoc e = (JarEntry JavaDoc)en.nextElement ();
347             if (e.getName ().endsWith (".class")) {
348                 int last = e.getName ().lastIndexOf ('/');
349                 if (last == -1) {
350                     // skip default pkg
351
continue;
352                 }
353                 String JavaDoc p = e.getName ().substring (0, last);
354
355                 if (pkgs == null) {
356                    packages.add (p);
357                    continue;
358                 }
359
360                 Boolean JavaDoc b = (Boolean JavaDoc)pkgs.get (p);
361                 if (b != null) {
362                     packages.add (p);
363                     continue;
364                 }
365
366                 String JavaDoc 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 JavaDoc)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 JavaDoc m = file.getManifest ();
385         if (m != null) {
386             String JavaDoc value = m.getMainAttributes ().getValue ("Class-Path");
387             if (value != null) {
388                 StringTokenizer tok = new StringTokenizer (value, " ");
389                 while (tok.hasMoreElements ()) {
390                     File JavaDoc sub = new File JavaDoc (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 JavaDoc output) throws BuildException, IOException JavaDoc {
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 JavaDoc output) throws BuildException, IOException JavaDoc {
414         PrintWriter w = new PrintWriter (new FileWriter (output));
415         Iterator it = external.iterator ();
416         
417         String JavaDoc SPACES = " ";
418         while (it.hasNext ()) {
419             File JavaDoc f = (File JavaDoc)it.next ();
420             
421             java.security.MessageDigest JavaDoc dig;
422             
423             try {
424                 dig = java.security.MessageDigest.getInstance ("MD5");
425             } catch (java.security.NoSuchAlgorithmException JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc output) throws BuildException, IOException JavaDoc {
456         TreeMap<String JavaDoc,List<ModuleInfo>> packages = new TreeMap<String JavaDoc,List<ModuleInfo>>();
457         
458         {
459             Iterator<ModuleInfo> it = modules.iterator ();
460             while (it.hasNext ()) {
461                 ModuleInfo m = it.next ();
462
463                 HashSet<String JavaDoc> pkgs = new HashSet<String JavaDoc>();
464                 iterateSharedPackages (m.file, pkgs);
465
466                 Iterator j = pkgs.iterator ();
467                 while (j.hasNext ()) {
468                     String JavaDoc s = (String JavaDoc)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 JavaDoc out = (String JavaDoc)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 JavaDoc f, Set<String JavaDoc> myPkgs) throws IOException JavaDoc {
499         JarFile JavaDoc file = new JarFile JavaDoc (f);
500         Enumeration<JarEntry JavaDoc> en = file.entries ();
501         LOOP: while (en.hasMoreElements ()) {
502             JarEntry JavaDoc 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 JavaDoc 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 JavaDoc m = file.getManifest ();
517         if (m != null) {
518             String JavaDoc value = m.getMainAttributes ().getValue ("Class-Path");
519             if (value != null) {
520                 StringTokenizer tok = new StringTokenizer (value, " ");
521                 while (tok.hasMoreElements ()) {
522                     File JavaDoc sub = new File JavaDoc (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 JavaDoc output, boolean implementationOnly) throws BuildException, IOException JavaDoc {
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 JavaDoc print = " REQUIRES ";
544                 if (d.exact && d.compare != null) {
545                     // ok, impl deps
546
} 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 JavaDoc output, boolean implementationOnly) throws BuildException, IOException JavaDoc {
571         PrintWriter w = new PrintWriter (new FileWriter (output));
572         
573         TreeMap<String JavaDoc, Set<Dependency>> groups = new TreeMap<String JavaDoc, 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 JavaDoc groupName = (String JavaDoc)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 JavaDoc print = " REQUIRES ";
601                 if (d.exact && d.compare != null) {
602                     // ok, impl deps
603
} else {
604                     if (implementationOnly) {
605                         continue;
606                     }
607                 }
608                 
609                 // special dependencies are ignored
610
if (d.isSpecial ()) {
611                     continue;
612                 }
613                 // dependencies within one group are not important
614
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     /** For a given dependency finds the module that this dependency refers to.
634      */

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     /** For a given codebasename finds module that we depend on
647      */

648     private ModuleInfo findModuleInfo (String JavaDoc 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 JavaDoc man, int dependencyType, String JavaDoc attrName) throws BuildException {
661         String JavaDoc 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 JavaDoc 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 JavaDoc name = dep.nextToken ().trim ();
677                 String JavaDoc equal = dep.nextToken ().trim ();
678                 String JavaDoc 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 JavaDoc {
688         public org.apache.tools.ant.types.FileSet jars;
689         public String JavaDoc 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 JavaDoc name) {
698             this.name = name;
699         }
700     }
701     
702     public static final class Output extends Object JavaDoc {
703         public OutputType type;
704         public java.io.File JavaDoc file;
705         
706         public void setType (OutputType type) {
707             this.type = type;
708         }
709         
710         public void setFile (File JavaDoc file) {
711             this.file = file;
712         }
713     }
714     
715     public static final class OutputType extends org.apache.tools.ant.types.EnumeratedAttribute {
716         public String JavaDoc[] getValues () {
717             return new String JavaDoc[] {
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 JavaDoc implements Comparable JavaDoc {
733         public final String JavaDoc group;
734         public final File JavaDoc file;
735         public final String JavaDoc codebasename;
736         public String JavaDoc publicPackages;
737     public Set/*String*/ friends;
738         public int majorVersion;
739         public String JavaDoc specificationVersion;
740         public String JavaDoc implementationVersion;
741         public Set<Dependency> depends;
742         public Set<Dependency> provides;
743         
744         public ModuleInfo (String JavaDoc g, File JavaDoc f, String JavaDoc a) {
745             this.group = g;
746             this.file = f;
747             this.codebasename = a;
748         }
749
750         public int compareTo (Object JavaDoc o) {
751             ModuleInfo m = (ModuleInfo)o;
752             return codebasename.compareTo (m.codebasename);
753         }
754
755         public boolean equals (Object JavaDoc 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 JavaDoc getName () {
767             if (majorVersion == -1) {
768                 return codebasename + " (" + group + ")";
769             } else {
770                 return codebasename + "/" + majorVersion + " (" + group + ")";
771             }
772         }
773
774         public String JavaDoc toString () {
775             return "ModuleInfo[" + getName () + "]";
776         }
777     } // end of ModuleInfo
778

779     private static final class Dependency extends Object JavaDoc implements Comparable JavaDoc {
780         public static final int PROVIDES = 1;
781         public static final int REQUIRES = 2;
782         
783         public final String JavaDoc 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 JavaDoc compare;
789         
790         
791         public Dependency (String JavaDoc token, int type, boolean exact, String JavaDoc compare) {
792             // base name
793
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 JavaDoc 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 JavaDoc o) {
816             Dependency m = (Dependency)o;
817             return token.compareTo (m.token);
818         }
819
820         public boolean equals (Object JavaDoc 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         /** These dependencies do not represent deps on real modules or
832          * tokens provided by real modules.
833          */

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 JavaDoc 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 JavaDoc toString () {
869             String JavaDoc t;
870             switch (type) {
871                 case REQUIRES: t = "requires "; break;
872                 case PROVIDES: t = "provides "; break;
873                 default:
874                     throw new IllegalStateException JavaDoc ("Unknown type: " + type);
875             }
876             
877             return "Dependency[" + t + getName () + "]";
878         }
879
880     } // end of Dependency
881
}
882
Popular Tags