KickJava   Java API By Example, From Geeks To Geeks.

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


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.File JavaDoc;
24 import java.util.*;
25 import java.util.ArrayList JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.regex.*;
28
29 import org.apache.tools.ant.BuildException;
30 import org.apache.tools.ant.DirectoryScanner;
31 import org.apache.tools.ant.Project;
32 import org.apache.tools.ant.Task;
33 import org.apache.tools.ant.types.FileSet;
34
35 /** Generates a file with index of all files.
36  *
37  * @author Jaroslav Tulach
38  */

39 public class JavadocIndex extends Task {
40     private File JavaDoc target;
41     private FileSet set;
42     private Map<String JavaDoc,List JavaDoc<Clazz>> classes = new HashMap<String JavaDoc,List JavaDoc<Clazz>>(101);
43     
44     /** The file to generate the index to.
45      */

46     public void setTarget (File JavaDoc f) {
47         this.target = f;
48     }
49
50     /** List of indexes to search in.
51      */

52     public void addPackagesList(FileSet set) throws BuildException {
53         if (this.set != null) {
54             throw new BuildException ("Package list can be associated only once");
55         }
56         this.set = set;
57     }
58     
59     public void execute() throws BuildException {
60         if (target == null) {
61             throw new BuildException ("Target must be set"); // NOI18N
62
}
63         if (set == null) {
64             throw new BuildException ("Set of files must be provided: " + set); // NOI18N
65
}
66         
67         DirectoryScanner scan = set.getDirectoryScanner(this.getProject());
68         File JavaDoc bdir = scan.getBasedir();
69         for (String JavaDoc n : scan.getIncludedFiles()) {
70             File JavaDoc f = new File JavaDoc(bdir, n);
71             parseForClasses (f);
72         }
73
74         try {
75             log ("Generating list of all classes to " + target);
76             PrintStream ps = new PrintStream (new BufferedOutputStream (
77                 new FileOutputStream (target)
78             ));
79             if (target.getName ().endsWith (".xml")) {
80                 printClassesAsXML (ps);
81             } else {
82                 printClassesAsHtml (ps);
83             }
84             ps.close ();
85         } catch (IOException ex) {
86             throw new BuildException (ex);
87         }
88     }
89
90     
91     
92     /** Stores parsed info in classes variable */
93     private void parseForClasses (File JavaDoc f) throws BuildException {
94         log ("Parsing file: " + f, Project.MSG_DEBUG);
95         try {
96             BufferedReader is = new BufferedReader (new FileReader (f));
97             
98             
99             String JavaDoc urlPrefix;
100             try {
101                 String JavaDoc fullDir = f.getParentFile ().getCanonicalPath ();
102                 String JavaDoc fullTgz = target.getParentFile ().getCanonicalPath ();
103                 
104                 if (!fullDir.startsWith (fullTgz)) {
105                     throw new BuildException ("The directory of target file must be above all parsed files. Directory: " + fullTgz + " the file dir: " + fullDir);
106                 }
107                 
108                 urlPrefix = fullDir.substring (fullTgz.length () + 1);
109             } catch (IOException ex) {
110                 throw new BuildException (ex);
111             }
112             
113             // parse following string
114
// <A HREF="org/openide/xml/XMLUtil.html" title="class in org.openide.xml">XMLUtil</A
115
String JavaDoc mask = ".*<A HREF=\"([^\"]*)\" title=\"(class|interface) in ([^\"]*)\"[><I]*>([\\p{Alnum}\\.]*)</.*A>.*";
116             Pattern p = Pattern.compile (mask, Pattern.CASE_INSENSITIVE);
117             // group 1: relative URL to a class or interface
118
// group 2: interface or class string
119
// group 3: name of package
120
// group 4: name of class
121

122             int matches = 0;
123             for (;;) {
124                 String JavaDoc line = is.readLine ();
125                 if (line == null) break;
126                 
127                 Matcher m = p.matcher (line);
128                 if (m.matches ()) {
129                     matches++;
130                     log ("Accepted line: " + line, Project.MSG_DEBUG);
131                     
132                     if (m.groupCount () != 4) {
133                         StringBuffer JavaDoc sb = new StringBuffer JavaDoc ();
134                         sb.append ("Line " + line + " has " + m.groupCount () + " groups and not four");
135                         for (int i = 0; i <= m.groupCount (); i++) {
136                             sb.append ("\n " + i + " grp: " + m.group (i));
137                         }
138                         throw new BuildException (sb.toString ());
139                     }
140                    
141                     Clazz c = new Clazz (
142                         m.group (3),
143                         m.group (4),
144                         "interface".equals (m.group (2)),
145                         urlPrefix + "/" + m.group (1)
146                     );
147                     if (c.name == null) throw new NullPointerException JavaDoc ("Null name for " + line + "\nclass: " + c);
148                     if (c.name.length () == 0) throw new IllegalStateException JavaDoc ("Empty name for " + line + "\nclass: " + c);
149                     
150                     log ("Adding class: " + c, Project.MSG_DEBUG);
151                     
152                     List JavaDoc<Clazz> l = classes.get(c.pkg);
153                     if (l == null) {
154                         l = new ArrayList JavaDoc<Clazz>();
155                         classes.put (c.pkg, l);
156                     }
157                     l.add (c);
158                 } else {
159                     log ("Refused line: " + line, Project.MSG_DEBUG);
160                 }
161             }
162             
163             if (matches == 0) {
164                 throw new BuildException ("No classes defined in file: " + f);
165             }
166             
167         } catch (java.io.IOException JavaDoc ex) {
168             throw new BuildException (ex);
169         }
170     }
171     
172     private void printClassesAsHtml (PrintStream ps) {
173         ps.println ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">");
174         ps.println ("<HTML>\n<HEAD><TITLE>List of All Classes</TITLE></HEAD>");
175         ps.println ();
176         for (String JavaDoc pkg : new TreeSet<String JavaDoc>(classes.keySet())) {
177             ps.println ("<H2>" + pkg + "</H2>");
178             for (Clazz c : new TreeSet<Clazz>(classes.get(pkg))) {
179                 ps.print ("<A HREF=\"" + c.url + "\">");
180                 if (c.isInterface) {
181                     ps.print ("<I>");
182                 }
183                 ps.print (c.name);
184                 if (c.isInterface) {
185                     ps.print ("</I>");
186                 }
187                 ps.println ("</A>");
188             }
189         }
190         ps.println ("</HTML>");
191     }
192
193     private void printClassesAsXML (PrintStream ps) {
194         ps.println ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
195         ps.println ("<classes>");
196         for (String JavaDoc pkg : new TreeSet<String JavaDoc>(classes.keySet())) {
197             for (Clazz c : new TreeSet<Clazz>(classes.get(pkg))) {
198                 ps.print ("<class name=\"");
199                 ps.print (c.name);
200                 ps.print ("\"");
201                 ps.print (" url=\"");
202                 ps.print (c.url);
203                 ps.print ("\"");
204                 ps.print (" interface=\"");
205                 ps.print (c.isInterface);
206                 ps.print ("\"");
207                 ps.print (" package=\"");
208                 ps.print (c.pkg);
209                 ps.print ("\"");
210                 ps.println (" />");
211             }
212         }
213         ps.println ("</classes>");
214     }
215     
216     /** An information about one class in api */
217     private static final class Clazz extends Object JavaDoc implements Comparable JavaDoc<Clazz> {
218         public final String JavaDoc pkg;
219         public final String JavaDoc name;
220         public final String JavaDoc url;
221         public final boolean isInterface;
222         public Clazz (String JavaDoc pkg, String JavaDoc name, boolean isInterface, String JavaDoc url) {
223             this.pkg = pkg;
224             this.name = name;
225             this.isInterface = isInterface;
226             this.url = url;
227         }
228         
229         /** Compares based on class names */
230         public int compareTo(Clazz o) {
231             return name.compareTo(o.name);
232         }
233
234         public String JavaDoc toString () {
235             return "PKG: " + pkg + " NAME: " + name + " INTERFACE: " + isInterface + " url: " + url;
236         }
237     } // end of Clazz
238
}
239
Popular Tags