使用Eclipse开发Maven插件-1/3

时间:2023-02-07 08:45:15

概要

1. 这是一个样例,基本照着《Maven实战》-徐晓斌,第17章照抄的;个人练手之作,不喜勿喷!

2. 代码行统计插件。

备注

  大量插件可从以下网站获得:

    1. http://maven.apache.org/plugins/

    2. http://mojo.codehaus.org/plugins.html

  m2e插件不能提供搜索框,搜索Maven依赖包的(书里说可以,但实际插件不提供该功能了),可以通过:

  https://repository.sonatype.org/index.html 搜索(可根据类名,包名,artifactId等信息查找)

正文

1. 创建Maven项目,archetype选择:maven-archetype-plugin

New--->Project…选择Maven Project

使用Eclipse开发Maven插件-1/3

使用Eclipse开发Maven插件-1/3

2. 删除MyMojo.java,新增CountMojo.java继承:org.apache.maven.plugin.AbstractMojo

package com.ckhuang.maven.plugin;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

/**
 * 
 * 统计项目文件的行数
 * 
 * @author ck.huang
 * 
 */
@Mojo(name = "count")
public class CountMojo extends AbstractMojo {

  private static final String[] INCLUDES_DEFAULT = new String[] {"xml", "java", "properties"};

  /**
   * 
   * 项目根目录
   * 
   */
  @Parameter(defaultValue = "${project.basedir}", property = "baseDir", required = true,
      readonly = true)
  private File baseDir;

  /**
   * 
   * 项目源文件目录
   * 
   */
  @Parameter(defaultValue = "${project.build.sourceDirectory}", property = "sourceDirectory",
      required = true, readonly = true)
  private File sourceDirectory;

  /**
   * 
   * 项目测试代码源文件目录
   * 
   */
  @Parameter(defaultValue = "${project.build.testSourceDirectory}",
      property = "testSourceDirectory", required = true, readonly = true)
  private File testSourceDirectory;

  /**
   * 
   * 运行时配置文件
   * 
   */
  @Parameter(defaultValue = "${project.build.reousrce}", required = true, readonly = true)
  private List<Resource> resources;

  /**
   * 
   * 测试时配置文件
   * 
   */
  @Parameter(defaultValue = "${project.build.testReousrce}", required = true, readonly = true)
  private List<Resource> testResources;

  /**
   * 要统计的文件格式<br/>
   * 默认为:java,xml,properties<br/>
   * 可通过配置includes属性修改
   */
  @Parameter(property = "includes")
  private String[] includes;

  public void execute() throws MojoExecutionException, MojoFailureException {
    if (includes == null || includes.length == 0) {
      includes = INCLUDES_DEFAULT;
    }
    try {
      getLog().info("includes " + Arrays.toString(includes));

      countDir(sourceDirectory);

      countDir(testSourceDirectory);

      countResource(resources);

      countResource(testResources);
    } catch (IOException e) {
      throw new MojoExecutionException("Unable to count lines of code.", e);
    }
  }

  /**
   * 统计文件目录下的文件总行数
   * 
   * @param dir 目录路径
   * @throws IOException
   */
  private void countDir(File dir) throws IOException {
    if (!dir.exists()) {
      return;
    }

    List<File> collected = new ArrayList<File>();

    collectFiles(collected, dir);

    int lines = 0;

    for (File sourceFile : collected) {
      lines += countLine(sourceFile);
    }

    String path = dir.getAbsolutePath().substring(baseDir.getAbsolutePath().length());

    getLog().info(path + ":" + lines + " lines of code in " + collected.size() + "files");
  }

  private int countLine(File sourceFile) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(sourceFile));

    int line = 0;
    try {
      while (reader.ready()) {
        reader.readLine();

        line++;
      }
    } finally {
      reader.close();
    }
    return line;
  }

  private void collectFiles(List<File> collected, File file) {
    if (file.isFile()) {
      for (String include : includes) {
        if (file.getName().endsWith("." + include)) {
          collected.add(file);

          break;
        }
      }
    } else {
      for (File sub : file.listFiles()) {
        collectFiles(collected, sub);
      }
    }
  }

  /**
   * 统计配置文件
   * 
   * @param resources
   * @throws IOException
   */
  private void countResource(List<Resource> resources) throws IOException {
    for (Resource res : resources) {
      countDir(new File(res.getDirectory()));
    }
  }

}

 

3. 在生成的POM,xml文件基础上修改,修改:goalPrefix

<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>com.ckhuang.maven</groupId>
  <artifactId>maven-loc-plugin</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>maven-plugin</packaging>

  <name>lineCounter Maven Plugin</name>

  <!-- FIXME change it to the project's website -->
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.version>3.0.4</maven.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>${maven.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.8.2</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>loc</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>run-its</id>
      <build>

        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-invoker-plugin</artifactId>
            <version>1.7</version>
            <configuration>
              <debug>true</debug>
              <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
              <pomIncludes>
                <pomInclude>*/pom.xml</pomInclude>
              </pomIncludes>
              <postBuildHookScript>verify</postBuildHookScript>
              <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
              <settingsFile>src/it/settings.xml</settingsFile>
              <goals>
                <goal>clean</goal>
                <goal>test-compile</goal>
              </goals>
            </configuration>
            <executions>
              <execution>
                <id>integration-test</id>
                <goals>
                  <goal>install</goal>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>

      </build>
    </profile>
  </profiles>
</project>

4. 修改Maven的setting.xml增加插件所属的groupId,以便更简易的访问:

<pluginGroups>
<!-- 你的插件groupId -->
<pluginGroup>com.ckhuang.maven</pluginGroup>
</pluginGroups>

5. 进入某个Maven项目,执行:

mvn loc:count

=========================================

PS,如果没有经过第4步,以及第3步中修改POM.xml的:

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-plugin-plugin</artifactId>
        <version>3.2</version>
        <configuration>
          <goalPrefix>loc</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>

则使用插件需要执行:

mvn com.ckhuang.maven:maven-loc-plugin:0.0.1-SNAPSHOT:count

搞定!

后记

涉及的细节如注解:@Mojo,@Parameter(property = "includes")等的使用,${project.build.reousrce}等Maven的环境变量,

将在下一章节进行说明。