Java实现扫描SVN项目代码检测是否符合规范

这两天在写一个java程序,可以检测其他的java项目的代码是否符合规范。并且能够对SVN中的项目进行检查。

第一步是先实现本地文件的扫描,很简单,就是一个文件遍历找出所有文件的代码:

/*
	  * 递归调用查找指定文件加下所有文件
	  */
	 public static  String GetFiles(String path) throws RowsExceededException, WriteException{
	  File rootDir = new File(path);
	   if(!rootDir.isDirectory()){
		   //调用检测代码的方法
		   checkLine(rootDir);
		   //清楚上下文记录
		   context.clear();
	   }else{
	    String[] fileList =  rootDir.list();
	    for (int i = 0; i < fileList.length; i++) {
	     path = rootDir.getAbsolutePath()+"\\"+fileList[i];
	     GetFiles(path);      
	      } 
	   }    
	  return null;    
	 }


第二步:循环读取文件中的每一行,并对每行进行分析:

if(rootDir.getName().endsWith(".java")){
			String path = rootDir.getAbsolutePath();
			System.out.println(path);
			FileInputStream scanFile = null;
			BufferedInputStream bin = null;
			InputStreamReader inread = null;
			BufferedReader br = null;
			   try {
				   scanFile = new FileInputStream(path);
				   bin = new BufferedInputStream(scanFile);
				   inread = new InputStreamReader(bin);
				   br = new BufferedReader(inread);
				String str = "";
				int i =1;
				while((str = br.readLine())!=null){//读取每一行代码,并调用parseLine方法来解析和检查
					parseLine(path, str, i);
					i++;
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				try {
					inread.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				try {
					bin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			   
		   }



第三步,对代码进行检测,这里使用正则表达式来判断当前行代码是属性,还是常量,还是方法定义,还是控制语句(if,for,while,switch)等,

这段检测的代码都是本人用正则来判断,也可以使用ASTView组件的API来获取java类中的属性,方法名,等,类似于反射技术。

	//如果当前行是定义属性,常量,或则局部变量
		if(temp.matches("(private|public|protecte)?\\s?[\\w<,>]*\\s\\w*;")
			|| temp.matches("(final)?\\s?[\\w<,>]*\\s\\w*(;|\\s?=\\s?\\w*;|"
					+ "\\s?=\\s?new\\s[\\w<,>]*\\(([\\w<,>\\s]*)?\\);|\\s?=\\s?\\(\\w*\\)\\s?[\\w\\.\\)\\(\"\\s]*;)")){
			//获取上下文中,当前行的前面一行代码
			String pre = context.get(i-2);
			//判断该属性,常量,或则局部变量的前面一行如果不是注释,则不符合规范。下面的正则可以匹配双斜杠和斜杠星
			if(!pre.trim().matches("/([\\w*]|[^\\x00-\\xff]|\\s)*/")){
				printXLS("错误规范66","定义的局部变量,常量,字段/属性必须有注释", path, "第"+i+"行");
				isStatus = true;
			}
		}



代码规范多达七八十条,在这里就不一一列举。

printXLS("错误规范66","定义的局部变量,常量,字段/属性必须有注释", path, "第"+i+"行");

printXLS是把错误报告写到Excel文件中。


第四部:编写代码从SVN中检出项目,这里需要用到SVNKit库,SVNKit是一个纯javasubversion客户端库。

代码如下:

/*第一步:
*导入可能用到的类
*/
import java.io.*;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;

public class SVNUtil {
	/*
	 * 第二步: 声明客户端管理类SVNClientManager。
	 */
	private static SVNClientManager ourClientManager;

	public static void checkOut() throws SVNException {
		/*
		 * 第三步: 对版本库进行初始化操作 (在用版本库进行其他操作前必须进行初始化) 对于通过使用 http:// 和 https://
		 * 访问,执行DAVRepositoryFactory.setup(); 对于通过使用svn:// 和
		 * svn+xxx://访问,执行SVNRepositoryFactoryImpl.setup();
		 * 对于通过使用file:///访问,执行FSRepositoryFactory.setup(); 本程序框架用svn://来访问
		 */

		SVNRepositoryFactoryImpl.setup();

		/*
		 * 第四步: 要访问版本库的相关变量设置
		 */
		// 版本库的URL地址
		SVNURL repositoryURL = null;
		try {
			repositoryURL = SVNURL.parseURIEncoded("svn://192.168.9.60/temp");
		} catch (SVNException e) {
			//
		}
		// 版本库的用户名
		String name = "test";
		// 版本库的用户名密码
		String password = "111111";
		// 工作副本目录
		String myWorkingCopyPath = "F:/SVN_JAVAScan";
		// 驱动选项
		ISVNOptions options = SVNWCUtil.createDefaultOptions(true);

		/*
		 * 第五步: 创建SVNClientManager的实例。提供认证信息(用户名,密码) 和驱动选项。
		 */
		ourClientManager = SVNClientManager.newInstance((DefaultSVNOptions) options, name, password);

		/*
		 * 第六步: 通过SVNClientManager的实例获取要进行操作的client实例(如 * SVNUpdateClient)
		 * 通过client实例来执行相关的操作。 此框架以check out操作来进行说明,其他操作类似。
		 */

		/* 工作副本目录创建 */
		File wcDir = new File(myWorkingCopyPath);
		if (wcDir.exists()) {
			System.out.println("the destination directory '" + wcDir.getAbsolutePath() + "' already exists!");
		} else {
			wcDir.mkdirs();
		}

		try {
			/*
			 * 递归的把工作副本从repositoryURL check out 到 wcDir目录。 SVNRevision.HEAD
			 * 意味着把最新的版本checked out出来。
			 */

			SVNUpdateClient updateClient = ourClientManager.getUpdateClient();
			updateClient.setIgnoreExternals(false);
			//需要遍历多个文件夹时,要传入递归深度参数为无限SVNDepth.INFINITY
			long workingVersion = updateClient.doCheckout(repositoryURL, wcDir, SVNRevision.HEAD, SVNRevision.HEAD,SVNDepth.INFINITY, true);
			System.out.println("把版本:"+workingVersion+" check out 到目录:"+wcDir+"中。");
		} catch (SVNException svne) {
			svne.printStackTrace();
		}
	}
}


上面就是检出SVN项目到本地中的方法,既然项目以及可以检出到本地指定的文件夹中。那么执行完上面的代码,下面的代码就是扫描文件,只需要将前面扫描文件的代码执行即可。





你可能感兴趣的:(Java之路)