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項目到本地中的方法,既然項目以及可以檢出到本地指定的文件夾中。那麼執行完上面的代碼,下面的代碼就是掃描文件,只需要將前面掃描文件的代碼執行即可。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章