前言
上一篇我们介绍了doclet及其命令行选项,最后是自己自定义的doclet1代码,思路很简单,就是利用doclet读取代码在方法上面的注解,然后将这些注解的值写到模板中,最后输出到指定位置。在第一代doclet中,自己将html模板,java模板,自定义标签名称等都写在一起,耦合性极强。这一篇就是利用freemarker将其中的模板从中抽出来,于是有了第二代doclet——doclet2
freemarker的简介
FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具,简而言之,就是:模板+数据模型=输出。
自己之所以决定使用它,最主要的原因有以下4点:
1.它能很方便得生成各种文本:HTML,XML,PTF,JAVA源代码等
2.是轻量级的框架,不需要Sservlet环境,易于嵌入到产品中
3.可以从任何源载入模板,如本地文件,数据库等
4.可以按需生成文本:保存到本地文件;作为email发送;从web应用程序发送它返回给web浏览器
这4点简直是量身为doclet打造的:自己所写的doclet2,并没有servlet环境;数据是从doclet中拿到的;最终不仅要生成html格式的文档,还要生成java类型的前端代码。
(ps:在java领域,表现层技术主要有三种:jsp、freemarker、velocity。大家有兴趣可以查一查这三种的优缺点)
freemarker的使用
freemarker的模板是.ftl文件,在文档编译器中编辑好模板,保存时以.ftl结尾即可。freemarker的语法和标签的使用,大家可以参考:http://demojava.iteye.com/blog/800204,写得很全,我就不赘述了。
freemarker的数据模型使用三种基本的对象类型:scalars(标量),hashes(哈希表),sequences(序列),除此之外,还有方法和用户自定义FTL标记两种,具体可参考
http://www.zzbaike.com/wiki/FreeMarker%E7%9A%84%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B
freemarker的合并主要是以下四个步骤:
1.创建Configuration实例,该实例负责管理FreeMarker的模板加载路径,生成模板实例。
Configuration cfg = new Configuration();
2.使用Configuration实例来生成Template实例,在这里需要指定使用的模板文件。
//指定模板路径
File file = new File("src");
//设置要解析的模板所在的目录,并加载模板文件
cfg.setDirectoryForTemplateLoading(file);
//设置编码方式
cfg.setDefaultEncoding("UTF-8");
Template indexTemplate = cfg.getTemplate("index.ftl");
3.填充数据模型,数据模型就是一个Map对象。
Map indexRoot = new HashMap();
4.调用Template实例的process方法完成合并。
//将要生成的文件
File indexfile = new File(DES_DIRPATH + "2.0.html");
//得到输出流
BufferedWriter write = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(indexfile),"UTF-8"));
//合并模板和数据
indexTemplate.process(indexRoot,write);
针对每个方法,自己要生成的html文档的ftl模板(文件名为:Method.ftl)如下:
<!DOCTYPE html>
<html>
<meta charset=utf8>
<head>
<title></title>
</head>
<style type="text/css">
body{
font: 12px/1.125 Arial, Helvetica, sans-serif;
}
.wiki_title{
line-height: 37px;
border-bottom: 1px solid #e5e5e5;
margin: 16px 0 8px 0;
font-size: 20px;
color: #333;
font-family: "Microsoft Yahei";
font-weight: 300;
}
h1.wiki_title{
font-size: 24px;
}
a{
color: #3c7cb3;
text-decoration: none;
}
table{
border-collapse: collapse;
border-spacing: 0;
}
table.parameters{
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
-webkit-border-horizontal-spacing: 0px;
-webkit-border-vertical-spacing: 0px;
width: 100%;
}
th,td{
text-align: center;
font-weight: bolder;
border: 1px solid #cccccc;
height: 20px;
}
.code_type{
text-transform: uppercase;
margin-bottom: 5px;
display: inline-block;*
display: inline;*
zoom: 1;
background: #b4e3b4;
border-radius: 2px;
color: