maven 自定义插件小示例

maven作为一个核心是插件的架构,所有的工作都通过插件来执行,主要分为两类build和report
[list]
[*]Build plugins:在build阶段执行,在pom中必须配置在<build/>标签里面
[*]Reporting plugins:在生成site阶段执行,在pom中配置在<reporting/>标签里面。
[/list]
maven官方已经给我们提供了各种各样的插件[url=http://maven.apache.org/plugins/]maven plugins[/url],但有时我们还是需要自己定义我们特殊的插件,比如我们项目中根据特定的文件,自动生成对应的java类,这时就需要我们实现自己的特定插件了,本示例包含两个工程,
[list]
[*]插件工程:maven-plugin-test
[*]使用插件的工程:maven-plugin-client-test
[/list]
为了使示例保持简单,插件工程只演示了从特定目录下读取特定文件类型,并没有生成java类。

1.插件工程
1.1 工程结构

[img]http://dl2.iteye.com/upload/attachment/0127/4498/74435980-540b-3c4b-875f-9c7372b6f843.png[/img]

1.2 Mojo类

/**
*
*/
package falcon.chengf.maven.plugin.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.model.fileset.FileSet;
import org.apache.maven.shared.model.fileset.util.FileSetManager;
import org.yaml.snakeyaml.Yaml;

/**
* read content from yaml files (.yml)
*
* @goal readyml
* @phase generate-sources
* @threadSafe
*/
public class ReadYmlMojo extends AbstractMojo {

/**
* The source directory of yml files. This directory is added to the
* classpath at schema compiling time. All files can therefore be referenced
* as classpath resources following the directory structure under the source
* directory.
*
* @parameter property="sourceDirectory"
* default-value="${basedir}/src/main/resources"
*/
private File sourceDirectory;

/**
* @parameter property="outputDirectory"
* default-value="${project.build.directory}/generated-sources/yml"
*/
private File outputDirectory;

/**
* @parameter property="sourceDirectory"
* default-value="${basedir}/src/test/resources"
*/
private File testSourceDirectory;

/**
* @parameter property="outputDirectory"
* default-value="${project.build.directory}/generated-test-sources/yml"
*/
private File testOutputDirectory;

/**
* A set of Ant-like inclusion patterns used to select files from the source
* directory for processing. By default, the pattern
* <code>**/*.yml</code> is used to select grammar files.
*
* @parameter property="includes"
**/

private String[] includes = new String[] { "**/*.yml" };

/**
* A set of Ant-like inclusion patterns used to select files from the source
* directory for processing. By default, the pattern
* <code>**/*.yml</code> is used to select grammar files.
*
* @parameter
*/
private String[] testIncludes = new String[] { "**/*.yml" };

/**
* A set of Ant-like exclusion patterns used to prevent certain files from
* being processed. By default, this set is empty such that no files are
* excluded.
*
* @parameter
*/
protected String[] excludes = new String[0];

/**
* A set of Ant-like exclusion patterns used to prevent certain files from
* being processed. By default, this set is empty such that no files are
* excluded.
*
* @parameter
*/
protected String[] testExcludes = new String[0];

/**
* The current Maven project.
*
* @parameter default-value="${project}"
* @readonly
* @required
*/
protected MavenProject project;

/*
* (non-Javadoc)
*
* @see org.apache.maven.plugin.Mojo#execute()
*/
public void execute() throws MojoExecutionException, MojoFailureException {
getLog().info("start to read content from yml file");
getLog().info("sourceDirectory:" + sourceDirectory.getAbsolutePath());
getLog().info("outputDirectory:" + outputDirectory.getAbsolutePath());
getLog().info("includes:" + Arrays.asList(includes));
boolean hasSourceDir = null != sourceDirectory && sourceDirectory.isDirectory();
boolean hasTestDir = null != testSourceDirectory && testSourceDirectory.isDirectory();
if (!hasSourceDir && !hasTestDir) {
throw new MojoExecutionException("neither sourceDirectory: " + sourceDirectory + " or testSourceDirectory: "
+ testSourceDirectory + " are directories");
}
if (hasSourceDir) {
String[] includedFiles = getIncludedFiles(sourceDirectory.getAbsolutePath(), excludes, getIncludes());
readFiles(includedFiles, sourceDirectory, outputDirectory);
}

if (hasTestDir) {
String[] includedFiles = getIncludedFiles(testSourceDirectory.getAbsolutePath(), testExcludes,
getTestIncludes());
readFiles(includedFiles, testSourceDirectory, testOutputDirectory);
project.addTestCompileSourceRoot(testOutputDirectory.getAbsolutePath());
}


getLog().info("read from yml file end");
}

/**
* 根据条件过滤需要处理的文件
* @param absPath
* @param excludes
* @param includes
* @return
*/
private String[] getIncludedFiles(String absPath, String[] excludes, String[] includes) {
FileSetManager fileSetManager = new FileSetManager();
FileSet fs = new FileSet();
fs.setDirectory(absPath);
fs.setFollowSymlinks(false);

for (String include : includes) {
fs.addInclude(include);
}
for (String exclude : excludes) {
fs.addExclude(exclude);
}
return fileSetManager.getIncludedFiles(fs);
}

private void readFiles(String[] files, File sourceDir, File outDir) throws MojoExecutionException {
for (String filename : files) {
getLog().info("read content from file " + filename);
try {
doRead(filename, sourceDir, outDir);
} catch (IOException e) {
throw new MojoExecutionException("Error compiling protocol file " + filename + " to " + outDir, e);
}
}
}

private static final Yaml yaml = new Yaml();

protected void doRead(String filename, File sourceDirectory, File outputDirectory) throws IOException {
File src = new File(sourceDirectory, filename);

// 通过snakeyml读取yml文件内容
Map<String,Object> content= (Map)yaml.load(new FileInputStream(src));
getLog().info(filename+"'s content is"+content.toString());
}


protected String[] getIncludes() {
return includes;
}

protected String[] getTestIncludes() {
return testIncludes;
}
}



注意点
[list]
[*]1.ReadYmlMojo类上面的注释中有三个注解,这三个注解有特定含义,不能省略,其中@goal 对应的值(readyml)必须和pom.xml中的goal一致
[*]2.属性上面注释中的@parameter注解也有特殊含义,不能省略,如sourceDirectory上的@parameter property="sourceDirectory"要和使用插件工程的pom中指定的参数一致
[/list]
1.3 插件工程的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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>falcon.chengf</groupId>
<artifactId>maven-plugin-test</artifactId>
<version>1.0</version>

<packaging>maven-plugin</packaging>

<name>maven-plugin-test</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.version>2.0.10</maven.version>
<file-management.version>1.2.1</file-management.version>
</properties>

<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>file-management</artifactId>
<version>${file-management.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<configuration>
<goalPrefix>readyml</goalPrefix>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
<execution>
<id>help-goal</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
</project>


可以看到 goalPrefix 对应的属性值和mojojava类中的值时一样的

2 使用插件的工程
2.1 工程结构

[img]http://dl2.iteye.com/upload/attachment/0127/4496/44ef0af2-580b-39b8-b6c7-beae1e606911.png[/img]
2.2 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>falcon.chengf</groupId>
<artifactId>maven-plugin-client-test</artifactId>
<version>0.0.1-SNAPSHOT</version>

<name>maven-plugin-client-test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<sourceDirectory>${project.basedir}/target/generated-sources</sourceDirectory>
<plugins>
<plugin>
<groupId>falcon.chengf</groupId>
<artifactId>maven-plugin-test</artifactId>
<version>1.0</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>readyml</id>
<phase>generate-sources</phase>
<goals>
<goal>readyml</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/resources/yml</sourceDirectory>
<outputDirectory>${project.basedir}/target/generated-sources</outputDirectory>
<includes>
<include>**/*.yml</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>falcon.chengf</groupId>
<artifactId>
maven-plugin-test
</artifactId>
<versionRange>
[0.0.1-SNAPSHOT,)
</versionRange>
<goals>
<goal>readyml</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>



注意点:
[list]
[*]execution中的id属性要和插件工程对应的goal一致
[*]configuration中的属性如outputDirectory要和插件工程中@parameter的property值一致
[*]在eclipse中引用插件工程后回报如下错误

[img]http://dl2.iteye.com/upload/attachment/0127/4494/ee642518-f29e-3e92-beb0-e779a937ac5c.png[/img]

直接选择第二项忽略即可
[/list]

在使用插件的工程中创建/src/main/resources/yml文件,存入test.yml内容如下:

name: chengf
level: 11


执行maven package命令,可以在控制台看到maven插件正确执行,解析的test.yml文件的内容
[img]http://dl2.iteye.com/upload/attachment/0127/4492/fc8e7dbc-65ce-3c23-9966-c401e4d11e59.png[/img]

完整工程代码请参考附件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值