正如我在“用Velocity进行配置文件信息的集中管理 ”————http://danlley.iteye.com/blog/106130 中的许诺,这个专题将专门说说如何在Maven2插件中用Velocity对配置文件的集中管理。有了上个专题的基础,我这里也就化繁就简了。下面这段代码是通过上个专题的例子进行改写、整理、重构以后的代码,核心任务就是处理配置文件。
- public class VelocitySamples{
- private VelocityContext context;
- /**
- *
comments : 程序入口
- *
- * author danlley
- * coding date 2007-7-24
- * @param path 资源文件路径,默认与Maven默认资源文件路径相同
- * @param template 资源仓库
- * @param destPath 目标路径,默认与Maven编译路径相同
- * @throws Exception
- */
- public void dealFile(String path,String template,String destPath) throws Exception{
- File[] files=new File(path).listFiles();
- String errMsg="请核对路径: "+path+" 确认是否有资源文件存在于此路径下.";
- if(files.length==0)
- throw new FileNotFoundException(errMsg);
- context=new VelocityContext();
- applyProperties(path+template);//initial the VelocityContext
- Velocity.init();
- for(File file:files){
- if(!file.isFile())
- continue;
- String origName=file.getName();
- if(!checkFile(origName))
- continue;
- createFile(origName,destPath,path);
- }
- }
- /**
- *
comments : 此方法用于检查文件是否为待处理文件,在本例子中待处理文件的后缀均为“*.danlley”
- * 如:log4j配置文件则为log4j.xml.danlley,转换后为log4j.xml
- *
- * author danlley
- * coding date 2007-8-6
- * @param origName
- * @return
- * @throws Exception
- */
- public boolean checkFile(String origName)throws Exception{
- int index=origName.lastIndexOf(".");
- String tail=origName.substring(index+1,origName.length());
- if("danlley".equals(tail))
- return true;
- else
- return false;
- }
- /**
- *
comments : 生成转换后的文件
- *
- * author danlley
- * coding date 2007-7-24
- * @param origFileName
- * @param destPath
- * @param targetPath
- * @throws Exception
- */
- public void createFile(String origFileName,String destPath,String targetPath) throws Exception{
- int index=origFileName.lastIndexOf(".");
- String destFileName=origFileName.substring(0,index);
- BufferedWriter writer=new BufferedWriter(new FileWriter(destPath+destFileName));
- Template template=Velocity.getTemplate(targetPath+origFileName);
- template.merge(context,writer);
- writer.flush();
- writer.close();
- }
- /**
- *
comments : 为 VelocityContext 获取替换信息
- *
- * author danlley
- * coding date 2007-7-24
- * @param path
- * @throws Exception
- */
- public void applyProperties(String path) throws Exception{
- FileInputStream fis=new FileInputStream(path);
- if(null==fis)throw new NullPointerException("broken file or bad file!");
- Properties prop=new Properties();
- prop.load(fis);
- Enumeration enu=prop.keys();
- while(enu.hasMoreElements()){
- String key=enu.nextElement().toString();
- String value=prop.get(key).toString();
- context.put(key,value);
- }
- }
- }
既然是Maven插件开发,那我这里也就用Maven来管理工程了,下面是POM的配置祥单:
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0modelVersion>
- <groupId>org.danlleygroupId>
- <artifactId>maven-velocity-pluginartifactId>
- <packaging>maven-pluginpackaging>
- <version>1.0version>
- <name>maven-velocity-pluginname>
- <url>http://maven.apache.orgurl>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.pluginsgroupId>
- <artifactId>maven-compiler-pluginartifactId>
- <configuration>
- <source>1.5source>
- <target>1.5target>
- configuration>
- plugin>
- plugins>
- build>
- <dependencies>
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junitartifactId>
- <version>4.0version>
- <scope>testscope>
- dependency>
- <dependency>
- <groupId>velocitygroupId>
- <artifactId>velocityartifactId>
- <version>1.4version>
- dependency>
- <dependency>
- <groupId>org.apache.mavengroupId>
- <artifactId>maven-plugin-apiartifactId>
- <version>2.0version>
- dependency>
- dependencies>
- project>
让我不解的是Maven在进行代码编译时采用的还是Older Pattern,但是我的代码又用到了一些JDK5的某些特性,万般无赖,我只好用下面的方式进行显式申明了:
- <plugin>
- <groupId>org.apache.maven.pluginsgroupId>
- <artifactId>maven-compiler-pluginartifactId>
- <configuration>
- <source>1.5source>
- <target>1.5target>
- configuration>
- plugin>
还需要强调的一点是下面这段代码,我这里没有用jar也没有用war,因为我写的不是资源包,而是插件:
- <packaging>maven-pluginpackaging>
接下来在src/main/scripts路径下定义文件velocity.mojos.xml。内容如下:
- <pluginMetadata>
- <mojos>
- <mojo>
- <goal>velocitygoal>
- <call>velocitycall>
- <description>Say Hello, World.description>
- mojo>
- mojos>
- pluginMetadata>
Maven 官方的说明中好像说mojo的文件命名必须与goal一致,因此,由于我的goal是velocity,那mojo也就成了velocity.mojos.xml。当然至于这个goal到最后回去call什么东西,其实这里并不是很重要了,只要在使用plugin的工程中声明你需要call什么东西就可以了。如果大家对Maven插件开发比较感兴趣,可以到http://danlley.iteye.com/blog/102159去看看我的另外一片专题文章,希望对大家能够有所帮助。有了这篇文章做基础,我下面也就省去部分Maven相关的概念,直接给出我实现的钩子程序了(需要说明的一点是,在下面的这段程序中,注释和代码同样重要)。
- package org.danlley.util.samples;
- import java.io.File;
- import org.apache.maven.plugin.AbstractMojo;
- import org.apache.maven.plugin.MojoExecutionException;
- /**
- * replace.
- *
- * @goal replace
- */
- public class VelocityMojo extends AbstractMojo {
- /**
- * scriptSourceDirectory.
- *
- * @parameter default-value="${project.build.scriptSourceDirectory}"
- */
- private String scriptSourceDirectory;
- /**
- * outputDirectory.
- *
- * @parameter default-value="${project.build.outputDirectory}"
- */
- private String outputDirectory;
- /**
- * template.
- *
- * @parameter default-value="${project.build.outputDirectory}"
- */
- private String template;
- public void execute() throws MojoExecutionException {
- try {
- getLog().info("+-----------------------------------------+");
- getLog().info("| Velocity Files: |");
- getLog().info("+-----------------------------------------+");
- listFile();
- VelocitySamples _instance = new VelocitySamples();
- _instance.dealFile(scriptSourceDirectory + "/", template, outputDirectory + "/");
- getLog().info("生成文件已经被放置在路径:"+outputDirectory+" 请核对!");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- *
comments : 只会列出需要处理的文件
- *
- * author danlley
- * coding date 2007-8-6
- * @throws Exception
- */
- public void listFile() throws Exception {
- File[] files = (new File(scriptSourceDirectory)).listFiles();
- for (File file : files) {
- VelocitySamples ve = new VelocitySamples();
- if (ve.checkFile(file.getName())) {
- getLog().info(file.getName());
- }
- }
- }
- }
接下来进行install,接受到 BUILD SUCCESSFUL消息意味着插件开发过程结束,下面说说使用。在需要使用该插件的Maven2工程中打开POM,加入如下代码:
- <build>
- <plugins>
- <plugin>
- <groupId>org.danlleygroupId>
- <artifactId>maven-velocity-pluginartifactId>
- <version>1.0version>
- <configuration>
- <template>sample_data.propertiestemplate>
- configuration>
- <executions>
- <execution>
- <phase>compilephase>
- <goals>
- <goal>replacegoal>
- goals>
- execution>
- executions>
- plugin>
- plugins>
- build>
加入工程以后我的测试执行结果如下:
F:\workspaces\maven-velocity-lab>mvn compile
[INFO] Scanning for projects...
[INFO] -------------------------------------------------------------------------
---
[INFO] Building maven-velocity-lab
[INFO] task-segment: [compile]
[INFO] -------------------------------------------------------------------------
---
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [velocity:replace {execution: default}]
[INFO] +-----------------------------------------+
[INFO] | Velocity Files: |
[INFO] +-----------------------------------------+
[INFO] dlmchibernate.cfg.xml.danlley
[INFO] log4j.xml.danlley
[INFO] dlhibernate.cfg.xml.danlley
[INFO] download_config.xml.danlley
[INFO] 生成文件已经被放置在路径:F:\workspaces\maven-velocity-lab\target\classes
请核对!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Mon Aug 06 16:38:58 CST 2007
[INFO] Final Memory: 5M/9M
[INFO] ------------------------------------------------------------------------
参考资料:http://maven.apache.org/guides/plugin/guide-java-plugin-development.html