001 
002 /*
003  *  JavaDoq 1.0 - DOCUment JAVA In Source
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.javadoq.com>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package com.javadoq;
021 
022 import java.io.File;
023 import java.io.FileReader;
024 import java.util.ArrayList;
025 import java.util.HashMap;
026 import java.util.List;
027 import java.util.Map;
028 
029 import com.javadoq.html.DoqCopy;
030 import com.javadoq.html.DoqHTMLAllFiles;
031 import com.javadoq.html.DoqHTMLIndex;
032 import com.javadoq.html.DoqHTMLJavaFile;
033 import com.javadoq.html.DoqHTMLPackage;
034 import com.javadoq.html.DoqHTMLPackages;
035 import com.javadoq.html.DoqStyleSheet;
036 import com.javadoq.jjtree.ASTCompilationUnit;
037 import com.javadoq.jjtree.JJTreeParser;
038 import com.javadoq.jjtree.ast.ImportNameVisitor;
039 import com.javadoq.jjtree.ast.NewTypeVisitor;
040 import com.javadoq.jjtree.ast.SuperTypeVisitor;
041 
042 /**
043  * <p>Converts Java source code to HTML documents.</p>
044  * 
045  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.javadoq.com" target="_blank">http://www.javadoq.com</a>
046  */
047 public final class JavaDoq
048 {
049     /**
050      * <p>Version of JavaDoq.</p>
051      * @since 1.0
052      */
053     public final static String VERSION = "JavaDoq 1.0 - DOCUment JAVA In Source";
054     private final static String COPYRIGHT =
055         "Copyright (c) 2008-2011 J.J.Liu <jianjunliu@126.com> http://www.javadoq.com";
056 
057     /**
058      * <p>Title for target HTML documents.</p>
059      * @since 1.0
060      */
061     public String title = "Java Source";
062     /**
063      * <p>Source directory name.</p>
064      * @since 1.0
065      */
066     public String src = "src";
067     /**
068      * <p>Target directory name.</p>
069      * @since 1.0
070      */
071     public String dst = "docs/src";
072 
073     /**
074      * <p>All packages of source code to convert.</p>
075      * @since 1.0
076      */
077     public final Map<String, JavaPackage> packages = new HashMap<String, JavaPackage>();
078 
079     private List<SourceFile> allFiles = null;
080 
081     /**
082      * <p>Gets all files of source code to convert.</p>
083      * @return All files of source code to convert.
084      * @since 1.0
085      */
086     public final List<SourceFile> getAllFiles() {
087         if (allFiles == null) {
088             allFiles = new ArrayList<SourceFile>();
089             for (JavaPackage pkg : packages.values()) {
090                 allFiles.addAll(pkg.files.values());
091             }
092         }
093         return allFiles;
094     }
095 
096     /**
097      * <p>Gets a {@link JavaPackage}.</p>
098      * @param qname The fully qualified name of the package.
099      * @return A {@link JavaPackage} that has <tt>qname</tt>.
100      * @since 1.0
101      */
102     public final JavaPackage findPackage(JavaName qname) {
103         do {
104             JavaPackage p = packages.get(qname.text);
105             if (p != null) {
106                 return p;
107             }
108             if (qname.isSimple) {
109                 return packages.get("");
110             } else {
111                 qname = qname.chopLast();
112             }
113         } while (true);
114     }
115 
116     /**
117      * <p>Gets a {@link JavaType}.</p>
118      * @param qname The fully qualified name of the Java type.
119      * @return A {@link JavaType} that has <tt>qname</tt>.
120      * @since 1.0
121      */
122     public final JavaType findType(JavaName qname) {
123         JavaPackage p = findPackage(qname);
124         if (p == null) {
125             return null;
126         }
127         return p.findType(qname.chopFirst(p.name));
128     }
129 
130     /**
131      * <p>Builds HTML documents by the definitions.</p>
132      * @since 1.0
133      */
134     public final void build() {
135         try {
136             System.out.println(VERSION);
137             System.out.println(COPYRIGHT);
138 
139             if (src == null) {
140                 src = ".";
141             }
142 
143             new File(dst).mkdirs();
144             new DoqStyleSheet(this).close();
145             new DoqCopy(this, "overview.html").close();
146             new DoqHTMLIndex(this).close();
147 
148             buildSource(src, new JavaPackage(this, JavaName.EMPTY));
149  
150             for (String k : new ArrayList<String>(packages.keySet())) {
151                 JavaPackage pkg = packages.get(k);
152                 if (pkg.files.isEmpty()) {
153                     packages.remove(k);
154                 }
155             }
156 
157             new DoqHTMLAllFiles(this).close();
158             new DoqHTMLPackages(this).close();
159             for (JavaPackage pkg : packages.values()) {
160                 new File(dst + File.separator + pkg.name.path()).mkdirs();
161                 new DoqHTMLPackage(pkg).close();
162             }
163 
164             for (SourceFile f : getAllFiles()) {
165                 if (f.isJava) {
166                     FileReader reader = new FileReader(f.source);
167                     JJTreeParser parser = new JJTreeParser(reader);
168                     ASTCompilationUnit node = parser.CompilationUnit();
169 
170                     new NewTypeVisitor(f).visit(node, null);
171                     reader.close();
172                 }
173             }
174 
175             for (SourceFile f : getAllFiles()) {
176                 if (f.isJava) {
177                     FileReader reader = new FileReader(f.source);
178                     JJTreeParser parser = new JJTreeParser(reader);
179                     ASTCompilationUnit node = parser.CompilationUnit();
180 
181                     new ImportNameVisitor(f).visit(node, null);
182                     new SuperTypeVisitor(f).visit(node, null);
183                     reader.close();
184                 }
185             }
186 
187             for (SourceFile f : getAllFiles()) {
188                 if (f.isJava || f.isJavaCC || f.isJJTree) {
189                     DoqHTMLJavaFile doqFile = new DoqHTMLJavaFile(f);
190                     doqFile.parse();
191                     doqFile.close();
192                 } else {
193                     new DoqCopy(this, f.pckg.name.path() + File.separator + f.name).close();
194                 }
195             }
196         } catch (Exception e) {
197             e.printStackTrace();
198         }
199     }
200 
201     // Scans source files in a package.
202     private final void buildSource(String dir, JavaPackage pkg) {
203         packages.put(pkg.name.text, pkg);
204         File d = new File(dir);
205         String[] a = d.list();
206         if (a == null) return;
207         for (String s : a) {
208             if ("package.html".equals(s)) {
209                 pkg.hasDescription = true;
210             }
211             String fn = dir + File.separator + s;
212             if (new File(fn).isFile()) {
213                 pkg.files.put(s, new SourceFile(fn, pkg, s));
214             } else {
215                 buildSource(fn, new JavaPackage(
216                         this,
217                         pkg.name.addLast(s)
218                 ));
219             }
220         }
221     }
222 
223     /**
224      * <p>Builds HTML documents from a console.</p>
225      * @param args Arguments
226      * @since 1.0
227      */
228     public static void main(String[] args) {
229         JavaDoq jdoq = new JavaDoq();
230         if (args.length < 3) {
231             System.out.println("Usage: java -jar javadoq.jar title srcdir destdir");
232         } else {
233             jdoq.src = new File(args[0]).getAbsolutePath();
234             jdoq.dst = new File(args[1]).getAbsolutePath();
235             jdoq.title = args[2];
236             jdoq.build();
237         }
238     }
239 }