现实世界里,很多事情并不定一会按流程发展。软件开发也不例外。很多时候,我们是先写代码(在XP开发中,可能是一个正常现象),再写设计文档的。
如果你的代码中已经有大量的注释(合符Java代码规范的注释),再在设计文档中写一个Class Spec(类说明)表格,是件很痛苦的事情。很快,你就会因没完没了的Copy & Paste而加班。我们是程序员,讲到底,我们的工作其实只有一个目的,让计算机为人类去做重复没趣的事情。
可以通过编写Java Doclet(是不是让你想起Applet/Servelet? 如果不清楚Doclet是什么,参考:http://java.sun.com/j2se/javadoc/)来处理Java 代码中的注释。
目标1:从一大堆源码中榨取类名,与类说明到一个表格中:
Ref | Class name | Description |
1 | com.TestData2 | Hi ListClass |
2 | com.TestData | Hi ListClass |
Doclet核心代码:
import org.apache.commons.lang.StringUtils; import com.sun.javadoc.ClassDoc; import com.sun.tools.javadoc.Main; public class Test {
/** * Doclet开始方法,将被下面的 main(} 方法间接调用 * * @param root 参见:http://java.sun.com/j2se/1.5.0/docs/guide/javadoc/doclet/spec/index.html?com/sun/javadoc/package-summary.html * @return */ public static boolean start(com.sun.javadoc.RootDoc root) { ClassDoc[] classes = root.classes(); template1.Formater t = new template1.Formater(); t.openFile("./test_output/template1.html"); for (int i = 0; i < classes.length; ++i) {//iterate所有Class Doc(类文档对象) ClassDoc doc = classes[i];//类文档对象 System.out.println("***" + classes[i]); if( StringUtils.isEmpty( doc.commentText() ) ) {//类注释为空 continue; } Model model = new Model( Integer.toString( i + 1 ), doc.qualifiedName(),//类全名 doc.commentText()//类注释 ); t.insertClass( model ); } t.closeFile(); return true; } public static void main(String [] arg) { System.out.println("Test"); Main.execute("javadoc", Test.class.getName(), new String[]{ "-private", "-sourcepath", "./test_data",//源文件位置 "-subpackages", "com",//要处理的package name }); }
} |
Model类:
public class Model { private String ref; private String className; private String desc; public String getRef() { return ref; } public void setRef(String ref) { this.ref = ref; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public Model() { super(); } public Model(String ref, String className, String desc) { super(); this.ref = ref; this.className = className; this.desc = desc; } } |
Formater类:
public class Formater { StringTemplateGroup group = new StringTemplateGroup( "myGroup" ); private Writer w; public void openFile(String file) { try { w = new FileWriter( file ); //write head InputStream in = this.getClass().getResourceAsStream( "/template1/docHead.html" ); String head = IOUtils.toString( in ); IOUtils.closeQuietly( in ); w.write( head ); } catch (IOException e) { throw new RuntimeException( e ); } } public void closeFile() { try { //write foot InputStream in = this.getClass().getResourceAsStream( "/template1/docFoot.html" ); String foot = IOUtils.toString( in ); IOUtils.closeQuietly( in ); w.write( foot ); } catch (IOException e) { throw new RuntimeException( e ); } IOUtils.closeQuietly( w ); } public void insertClass(Model model) { try { w.write( formatClass( model ) ); } catch (IOException e) { throw new RuntimeException( e ); } } public String formatClass(Model model) { StringTemplate template = group.getInstanceOf( "template1/rec" ); template.reset(); template.setAttribute( "model", model ); return template.toString(); } } |
用到的组件:
目标2:
Analysis Class Name | TestData2 |
Package Name | com |
Modifier | public |
Type | Class |
Description | Hi ListClass |
Attribute Name | Modifier | Attribute Type | *Default Value | Description |
v | private | java.lang.StringBuffer | - | The v.Hi the v |
p | private | java.lang.StringBuffer | - | The p.Hi the p |
Operation | start | |
Modifier | public static | |
Operation Description | start method | |
Return Result | boolean | |
Throws | java.lang.Exception | |
Owned Parameter Name | Owned Parameter Type | Owned Parameter Description |
root | com.sun.javadoc.RootDoc | the root hi root |
Analysis Class Name | TestData |
Package Name | com |
Modifier | public |
Type | Class |
Description | Hi ListClass |
Attribute Name | Modifier | Attribute Type | *Default Value | Description |
v | private | java.lang.StringBuffer | - | The v.Hi the v |
p | private | java.lang.StringBuffer | - | The p.Hi the p |
Operation | start | |
Modifier | public static | |
Operation Description | start method | |
Return Result | boolean | |
Throws | java.lang.Exception | |
Owned Parameter Name | Owned Parameter Type | Owned Parameter Description |
root | com.sun.javadoc.RootDoc | the root hi root |
源码懒得再描述了,请看附件(http://blog.ccidnet.com/blog.php?do=showone&uid=38493&type=blog&itemid=170794)中的Eclipse project.