Maven Maven Plugin Example: Write your own maven plugin

Source: Internet
Author: User
Tags xmlns
Requirements:

When Maven compiles a project, the amount of statistical code, that is, the number of files in the project, the number of lines of code, including Java files and configuration files Two, where the configuration file (SQL, XML, properties) code lines/4 processing.


To Create a project:

First make sure that the M2eclipse plugin is installed: http://eclipse.org/m2e/

Eclipse-new-maven Project, select archetype = Maven-archetype-plugin: (or use the command mvn archetype:generate, and then follow the instructions)

The next step is to set up the coordinate information to create a MAVEN plugin project.

The resulting pom.xml files are as follows (with manual changes, see note):

<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.alpha.wang</groupId> <artifactId> Maven-statis-plugin</artifactid> <version>0.0.1-SNAPSHOT</version> <packaging> maven-plugin</packaging> <name>alpha-statis-plugin Maven plugin</name> <url>http:// Blog.csdn.net/vking_wang</url> <properties> <project.build.sourceencoding>utf-8</ project.build.sourceencoding> </properties> <dependencies> <dependency> <groupid&gt ;org.apache.maven</groupid> <artifactId>maven-plugin-api</artifactId> <version>2.0< /version> </dependency> <!--Otherwise, the Org.apache.maven.model.Resource in Mojo cannot be resolved--&GT     <dependency>         <groupid>org.apache.maven</ groupid>         <artifactId>maven-model</artifactId>         <version>2.2.1</version>     </dependency>  < dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <versi on>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <b
        uild> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>2.5.1</version> <configur ation> <!--[Warning]goal prefix is specified as: ' Maven-statis-plugin '. Maven currently expects it to be ' statis ' .--> <!--goalprefix>maVen-statis-plugin</goalprefix--> <goalPrefix>statis</goalPrefix> </configuration&gt
        ; <executions> <execution> <id>generated-helpmojo</id> &LT;GOALS&G
              T
      <goal>helpmojo</goal> </goals> </execution> </executions> </plugin> <!--generics is not supported In-source 1.3 (Use-source 5 or higher to enable generics)--&G
      T <plugin> <groupId>org.apache.maven.plugins</groupId> &LT;ARTIFACTID&GT;MAVEN-COMPILER-PL ugin</artifactid> <version>2.5.1</version> <configuration> <source&gt ;1.5</source> <target>1.5</target> </configuration> </plugin&gt
    ; </plugins> </build> </project>

Note that packing is Maven-plugin, and has a dependency on maven-plugin-api.

A source file for the public class Mymojo extends Abstractmojo is also generated automatically. Writing Mojo

Mojo = Maven old Java Object, you need to inherit Abstractmojo and implement its Execute method.

The previous step has automatically generated a mojo, we delete the recreate one:

Import Org.apache.maven.model.Resource;
Import Org.apache.maven.plugin.AbstractMojo;
Import org.apache.maven.plugin.MojoExecutionException; /** * * @goal count * * @phase process-sources */public class Countmojo extends Abstractmojo {private static FINA	
	L string[] Includes_default = {"Java", "xml", "SQL", "Properties"};
	private static final string[] Ratios_default = {"1.0", "0.25", "0.25", "0.25"};
    private static final String DOT = ".";
    /** * @parameter expression= "${project.basedir}" * @required * @readonly */private File basedir; /** * @parameter expression= "${project.build.sourcedirectory}" * @required * @readonly */priv
    Ate File SourceDir; /** * @parameter expression= "${project.build.testsourcedirectory}" * @required * @readonly */priv
    Ate File Testsourcedir; /** * @parameter expression= "${project.resources}" * @required * @readonly */Private List<reso Urce> resources;
    private list<file> resources; /** * @parameter expression= "${project.testresources}" * @required * @readonly */Private list<
    Resource> testresources;
    Private list<file> testresources;
    /** * @parameter * * Private string[] includes; /** * @parameter */private string[] Ratios;//todo defined as double[], prompting java.lang.ClassCastException when reading from XML: [D can
    
    Not being cast to [Ljava.lang.Object;
    Private map<string, double> ratiomap = new hashmap<string, double> ();
    Private long realtotal;

    Private long faketotal;
    	public void execute () throws Mojoexecutionexception {Initratiomap ();
    		try{Countdir (SourceDir);
    		
    		Countdir (Testsourcedir);
    		for (Resource res:resources) {countdir (New File (Res.getdirectory ()));
    		} for (Resource res:testresources) {countdir (New File (Res.getdirectory ())); } Getlog (). Info ("Total LINES:" +faketotal+ "(" +realtotal+ ")");
    	}catch (IOException e) {throw new Mojoexecutionexception ("Unable to count lines of code", e); }
       
    }
}


The tool method that is called is defined as follows:

    private void Initratiomap () throws mojoexecutionexception{if (includes = = NULL | | includes.length = 0) {in
    		Cludes = Includes_default;
    	ratios = Ratios_default;
    		} if (ratios = = NULL | | ratios.length = = 0) {ratios = new string[includes.length];
    		for (int i=0; i<includes.length; i++) {Ratios[i] = "1.0"; }} if (Includes.length! = ratios.length) {throw new Mojoexecutionexception ("Pom.xml error:the length of I
    	Ncludes is inconsistent with ratios! ");}
    	Ratiomap.clear ();
    	for (int i=0; i<includes.length; i++) {ratiomap.put (Includes[i].tolowercase (), double.parsedouble (Ratios[i]));
    	}} private void Countdir (File dir) throws IOException {if (! dir.exists ()) {return;
    	} list<file> collected = new arraylist<file> ();
    	
    	Collectfiles (collected, dir);
    	int realline = 0;
    	int fakeline = 0; for (File file:collected) {int[] line = CouNtline (file);
    		Realline + = line[0];
    	Fakeline + = line[1];
    	The String path = Dir.getabsolutepath (). substring (Basedir.getabsolutepath (). Length ()); StringBuilder info = new StringBuilder (). Append (Path). Append (":"). Append (Fakeline). Append ("(" +realline+ ")"). App
    	End ("Lines of code in"). Append (Collected.size ()). Append ("files");    	
    	
    GetLog (). info (info.tostring ()); The private void Collectfiles (list<file> collected, File file) throws ioexception{if (File.isfile (
    		) {if (isfiletypeinclude (file)) {collected.add (file);
    		}}else{for (File files:file.listFiles ()) {collectfiles (collected, files); }}} private int[] countline (file file) throws ioexception{BufferedReader reader = new Buff
    	Eredreader (new FileReader (file));
    	int realline = 0;
    			try{while (Reader.ready ()) {reader.readline ();
    		Realline + +;
}}finally{    		Reader.close ();
    	} int fakeline = (int) (Realline * getratio (file));
    	Realtotal + = Realline;
    	
    	Faketotal + = Fakeline; StringBuilder info = new StringBuilder (). Append (File.getname ()). Append (":"). Append (Fakeline). Append ("(" +realline+ "
    	). Append ("lines");
    	
    	GetLog (). Debug (Info.tostring ());
    return new Int[]{realline, fakeline};
    	} private double Getratio (file file) {double ratio = 1.0;
    	String type = getfiletype (file);
    	if (Ratiomap.containskey (type)) {ratio = Ratiomap.get (type);
    } return ratio;
    	Private Boolean isfiletypeinclude (file file) {Boolean result = false;
    	String fileType = getfiletype (file);    		
    	if (FileType! = null && ratiomap.keyset (). Contains (Filetype.tolowercase ())) {result = true;
    } return result;
    	private string Getfiletype (file file) {string result = NULL; String fname = File.getnamE ();
    	int index = Fname.lastindexof (DOT);
    		if (Index > 0) {String type = fname.substring (index+1);
    	result = Type.tolowercase ();
    } return result;
     }

Note here annotationUse, such as @parameter expression= "${project.build.sourcedirectory}", will automatically assign the project source code path to the SourceDir variable.

Pay special attention to @goal, each plug-in can have multiple targets, this goal is needed when using the MVN command. execution

You can use the MVN clean install to install the custom plugin to the local repository.

MVN clean Install
Then, under the project directory where statistics are needed, call the following command to count the lines of code:

MVN Com.alpha.wang:maven-statis-plugin:0.0.1-snapshot:count
The last colon is followed by the @goal defined above.

Obviously this command is too long, it is inconvenient to use, can be configured in Settings.xml as follows:

	<pluginGroups>
		<pluginGroup>com.alpha.wang</pluginGroup>
	</pluginGroups>
So the above command can be abbreviated as:

MVN Statis:count

provide configuration points

The includes and ratios variables of Mojo are marked as @parameter, indicating that the user can configure the field in Pom.xml, for example by adding the following to the pom.xml of the target project:

	<build>
		<plugins>
		    <plugin>
				<groupId>com.alpha.wang</groupId>
				<artifactId>maven-statis-plugin</artifactId>
				<version>0.0.1-SNAPSHOT</version>
				<configuration>
					<includes>
					   <!--include>java</include-->
					   <include >properties</include>
					</includes>
					<ratios>
					   <ratio>1.5</ratio>
					</ratios>
				</configuration>
			</plugin>
When you run MVN Statis:count on the project, only the properties file is counted and the amount of code is *1.5.

D:\>MVN statis:count
[INFO] scanning for projects ...
[INFO] searching repository for plugin with prefix: ' Statis '.
[INFO]------------------------------------------------------------------------
[info] Building com ....
[info]    task-segment: [Statis:count]
[INFO]--------------------------------------------- ---------------------------
[INFO] [statis:count]
[info] \src\main\java:0 (0) lines of code in 0 FILES
[info] \src\main\resources:18 (lines of code in 1 files
[info] Total lines:18 ()

[INFO]------- -----------------------------------------------------------------
[INFO] BUILD successful
[INFO]---------- --------------------------------------------------------------
[INFO] Total time: < 1 second
[INFO] Finished At:tue Feb 17:11:22 CST

[INFO] Final memory:6m/215m [INFO]------------------------------------ ------------------------------------


binding plug-ins

So each time you have to manually execute the command to count the amount of code. We can bind a plug-in to a phase of the lifecycle, such as the install phase, and automatically count the amount of code each time the item is install.

Modify the Pom file for the target project, and note the

	<build>
		<plugins>
		        <plugin>
				<groupId>com.alpha.wang</groupId>
				<artifactId>maven-statis-plugin</artifactId>
				<version>0.0.1-SNAPSHOT</version>
				<configuration>
					<includes>
					   <include>java</include>
					   <include> properties</include>
					</includes>
					<ratios>
					   <ratio>1.0</ratio>
					   <ratio>0.5</ratio>
                                        </ratios>
				</configuration>
				<executions>
					<execution>
						<id>count line number</id>
						<phase>install</phase>
						<goals>
							<goal>count</goal>							
						</goals>
					</execution>
				</ Executions>
			</plugin>





Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.