【功能与使用说明】
功能:
1、比较properties文件的key在resources与online-resources目录下是否相同(即在resources/x.properties中存在的key必须在online-resources/x.properties中存在),不同则置build faild.
2、若某文件或目录存在于resources中,而不存在于online-resources中,则用[warning]警告打印提示。
3、插件有两种模式:默认校验和指定校验
- 默认校验,即自动把所有存在于online-resources目录下的properties文件与resources下对应的properties文件进行校验
- 指定校验,即自己指定要校验的properties文件的文件名,必须同时存在于online-resources、resources目录下
使用说明:
1、 该插件有至少两个参数(n为参数目,n>=2);
2、 当n=2时表示默认校验,分别为线下资源路径和线上资源路径,在<offlinePath>与<onlinePath>标签下指定;
3、 当参数n>2时表示指定校验,<fileNames>的<param>属性中写明要校验的properties文件的名字;
【默认校验示例】
在父POM文件中如下位置加入<plugin>标签下的代码,所有子POM文件可以继承
<build>
<pluginManagement>
<plugins>
... ...
<plugin>
<groupId>com.baidu.unbiz</groupId>
<artifactId>check-maven-conf</artifactId>
<version>1.0.3</version>
<configuration>
<offlinePath>${project.basedir}/src/main/resources</offlinePath>
<onlinePath>${project.basedir}/src/main/online-resources</onlinePath>
</configuration>
<executions>
<execution>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
... ...
</plugins>
</pluginManagement>
</build>
但仍然需要在各个子POM中声明使用该插件,在如下位置加入<plugin>标签下代码即可完成所有默认配置:
<build>
<plugins>
... ...
<plugin>
<groupId>com.baidu.unbiz</groupId>
<artifactId>check-maven-conf</artifactId>
</plugin>
... ...
</plugins>
</build>
【指定校验示例】
父POM中的配置不变,只需要在想要进行指定校验的子POM中加入properties文件的名字即可:
<build>
<plugins>
... ...
<plugin>
<groupId>com.baidu.unbiz</groupId>
<artifactId>check-maven-conf</artifactId>
<configuration>
<fileNames>
<param>adx.properties</param>
<param>tpl/demo.properties</param>
</fileNames>
</configuration>
</plugin>
... ...
</plugins>
</build>
源码如下:
结构: com.baidu.unbiz.check / CheckMavenConf.java、CompareConf.java、ComparePropertiesKey.java
com.baidu.unbiz.deal.vertify / AbstractVerifyingResources.java 、VerifyingResources.java
com.baidu.unbiz.util / constantUtil.java
package com.baidu.unbiz.check;
import com.baidu.unbiz.deal.verify.VerifyingResources;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
/**
* @goal run
* @phase compile
*/
public class CheckMavenConf extends AbstractMojo {
/**
* @parameter default-value="${offlinePath}"
*/
private String offlinePath;
/**
* @parameter default-value="${onlinePath}"
*/
private String onlinePath;
/**
* @parameter default-value="${fileNames}"
*/
private String[] fileNames;
public void execute() throws MojoExecutionException, MojoFailureException {
VerifyingResources verResources = new VerifyingResources();
CompareConf compConf = new ComparePropertiesKey();
getLog().info("========================== validate starts ==========================");
if (!verResources.validate(offlinePath, onlinePath)) {
throw new MojoFailureException("The [" + offlinePath + "] or [" + onlinePath
+ "] you input was not valid directory!..");
} else {
getLog().info("========================== validate ends ==========================");
}
// 文件存在与resource而不存在于online-resources,则警告输出
compConf.warning(offlinePath, onlinePath);
getLog().info("==========================check starts==========================");
boolean hasError = false;
// 如果是人工指定的比较配置文件
if (VerifyingResources.isManual(fileNames)) {
hasError = compConf.compare(offlinePath, onlinePath, fileNames);
} else {
// 默认的扫描所有online-resources下的属性文件
String[] defaultFiles = compConf.validFilesToCompare(offlinePath, onlinePath);
hasError = compConf.compare(offlinePath, onlinePath, defaultFiles);
}
if (hasError) {
throw new MojoExecutionException(
"The keys listed above don't exist in online-resources.Please fix it before maven build!..");
} else {
getLog().info("==========================check ends==========================");
}
}
}
package com.baidu.unbiz.check;
/**
* 校验资源文件接口
* <p>
*
* @author zhoudongdong
* @date 2015年6月3日
*/
public interface CompareConf {
/**
* 校验资源文件
*
* @param offlinePath 线下资源路径
* @param onlinePath 线上资源路径
* @param fileNames 文件名
* @return boolean
*
* @author zhoudongdong 2015年6月17日
*/
public boolean compare(String offlinePath, String onlinePath, String[] fileNames);
/**
* 在online-resources文件中的为默认要比较的
*
* @param offlinePath 线下资源路径
* @param onlinePath 线上资源路径
* @return String[]
*
* @author zhoudongdong 2015年6月16日
*/
public String[] validFilesToCompare(String offlinePath, String onlinePath);
/**
* 文件存在与resource而不存在于online-resources,则警告输出
*
* @param offlinePath
* @param onlinePath
*
* @author zhoudongdong 2015年6月17日
*/
public void warning(String offlinePath, String onlinePath);
}
package com.baidu.unbiz.check;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Properties;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import com.baidu.unbiz.util.ConstantUtil;
/**
* 此类中实现对配置文件的比较及相关方法
* <p>
*
* @author zhoudongdong
* @date 2015年6月2日
*/
public class ComparePropertiesKey extends AbstractMojo implements CompareConf {
public boolean compare(String offlinePath, String onlinePath, String[] fileNames) {
InputStream offlineIns = null;
InputStream onlineIns = null;
Properties offlineProp = null;
Properties onlineProp = null;
boolean hasError = false;
// 对输入的文件进行循环
for (int i = 0; i < fileNames.length; ++i) {
try {
offlineIns = new FileInputStream(offlinePath + "/" + fileNames[i]);
onlineIns = new FileInputStream(onlinePath + "/" + fileNames[i]);
// 加载resources目录下的.properties
offlineProp = new Properties();
offlineProp.load(offlineIns);
// 加载online-resources目录下的.properties
onlineProp = new Properties();
onlineProp.load(onlineIns);
Enumeration<?> offlineKeys = offlineProp.propertyNames();
// 循环resources目录下的.properties所有的key
while (offlineKeys.hasMoreElements()) {
String key = (String) offlineKeys.nextElement();
// 如果online-resources对应的.properties文件没有改key
if (!onlineProp.containsKey(key)) {
getLog().error("The key " + key + " was not found in " + onlinePath + "\\" + fileNames[i]);
hasError = true;
}
}
} catch (FileNotFoundException e) {
System.out.println("File does not exists|" + fileNames[i]);
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (offlineIns != null) {
try {
offlineIns.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (onlineIns != null) {
try {
onlineIns.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return hasError;
}
public String[] validFilesToCompare(String offlinePath, String onlinePath) {
File resources = new File(offlinePath);
File onlineResources = new File(onlinePath);
HashSet<String> onlineSet = new HashSet<String>();
HashSet<String> offlineSet = new HashSet<String>();
// 获取resources路径下的所有.properties文件
for (String fileName : resources.list()) {
if (hasSuffix(fileName, ConstantUtil.PROPERTIES_SUFFIX)) {
offlineSet.add(fileName);
}
}
// 取出online-resources路径下的所有.properties文件名
for (String fileName : onlineResources.list()) {
if (hasSuffix(fileName, ConstantUtil.PROPERTIES_SUFFIX)) {
onlineSet.add(fileName);
}
}
String[] fileNames = new String[onlineSet.size()];
int index = 0;
for (String str : onlineSet) {
fileNames[index++] = str;
}
return fileNames;
}
/**
* 判断文件名是否以该后缀名结尾
*
* @param fileName 文件名
* @param suffix 要匹配的后缀名
* @return boolean
*
* @author zhoudongdong 2015年6月17日
*/
private boolean hasSuffix(String fileName, String suffix) {
String getSuffix = fileName.substring(fileName.lastIndexOf(".") + 1);
if (getSuffix.equalsIgnoreCase(suffix)) {
return true;
}
return false;
}
public void execute() throws MojoExecutionException, MojoFailureException {
}
public void warning(String offlinePath, String onlinePath) {
File resources = new File(offlinePath);
File onlineResources = new File(onlinePath);
HashSet<String> set = new HashSet<String>();
for (String fileName : onlineResources.list()) {
set.add(fileName);
}
for (String fileName : resources.list()) {
if (!set.contains(fileName)) {
getLog().warn("The file or directory " + fileName + " does not exist in online-resources!..");
}
}
}
}
package com.baidu.unbiz.deal.verify;
import java.io.File;
/**
* 抽象资源验证类
* <p>
*
* @author zhoudongdong
* @date 2015年6月3日
*/
public abstract class AbstractVerifyingResources {
/**
* 开始检查资源文件前的资源验证
*
* @param params 入参
* @return boolean
*/
public abstract boolean validate(String offline, String online);
/**
* 判断输入的路径是否是合法目录
*
* @param resource 测试环境资源路径
* @param onlineResouces 线上环境资源路径
* @return boolean
*/
public boolean isDirectory(String offlinePath, String onlinePath) {
File resources = new File(offlinePath);
File onlineResources = new File(onlinePath);
if (resources.isDirectory() && onlineResources.isDirectory()) {
return true;
}
return false;
}
/**
* 判断是否需要人工指定比较文件
*
* @param params 入参
* @return boolean
*/
public static boolean isManual(String[] params) {
if (params != null && params.length > 0) {
return true;
}
return false;
}
}
package com.baidu.unbiz.deal.verify;
/**
* 这个类中实现一些对资源进行验证的相关方法
* <p>
*
* @author zhoudongdong
* @date 2015年6月2日
*/
public class VerifyingResources extends AbstractVerifyingResources {
@Override
public boolean validate(String offline, String online) {
if (!isDirectory(offline, online)) {
return false;
}
return true;
}
}
package com.baidu.unbiz.util;
/**
* 常量
* <p>
*
* @author zhoudongdong
* @date 2015年6月3日
*/
public interface ConstantUtil {
/**
* 属性文件后缀
*/
String PROPERTIES_SUFFIX = "properties";
}