`
bruce008
  • 浏览: 173030 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

利用JDT 来分析java 源代码

    博客分类:
  • CI
 
阅读更多

项目里需要扫代码的sql,主要是想找出所有用到的sql。 将相关的sql 提交给DBA 来分析,希望在最早的时间发现潜在的查询性能问题。

想想eclipse 里面用到的JDT 能分析java 源代码, 如果我们能分析项目里的源代码利用ASTParser 就可以找到相关的SQL 定义了。

 

其实已经有人想到这个 http://www.programcreek.com/2011/01/a-complete-standalone-example-of-astparser

,已经自己整理过所有会依赖的jar,机器重装本地的 repository给丢了。  所有就直接用这个链接里面给的一个zip 包, 但是在我现在用到的eclipse 还需要 一个 org.eclipse.text_3.5.0.jar 。

 

为了这个代码不要弄丢了,直接放一份 当然没有项目里面的信息

package com.bwang.jdt;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;

public class SqlExtractor {
	private BufferedWriter writer;
	private long counter = 0;
	private final String fileRoot;
	private final String logFileName;

	public static void main (String[] args) {
		if (args.length < 2) {
			System.out.println("Please provide the parameters:");
			System.out.println("SqlExtractor  codeOfRoot logFileName");
			System.exit(-1);
		}
		SqlExtractor sqlExtractor = new SqlExtractor(args);
		sqlExtractor.extractSql();
	}

	SqlExtractor(String[] args) {
		fileRoot = args[0];
		logFileName =  args[1];

		try {
			writer = new BufferedWriter(new FileWriter(new File(logFileName)));
		} catch(IOException e) {

		}
	}

	private void analyzeOneFile(String sourceFile,  Writer writer) {
		String source = getFileContent(sourceFile);
		ASTParser parser = ASTParser.newParser(AST.JLS3);
		parser.setSource(source.toCharArray());
		CompilationUnit unit = (CompilationUnit)parser.createAST(null);
		unit.recordModifications();
		StringBuilder sb = new StringBuilder();
		List<AbstractTypeDeclaration> types = unit.types();
		for (AbstractTypeDeclaration type : types) {
			if (type.getNodeType() == ASTNode.TYPE_DECLARATION) {
				// Class def found
				List<BodyDeclaration> bodies = type.bodyDeclarations();
				for (BodyDeclaration body : bodies) {
					if (body.getNodeType() == ASTNode.FIELD_DECLARATION /*&& 
	                		((FieldDeclaration)body).getType().equals(Type.S) */	) {
						FieldDeclaration field = (FieldDeclaration)body;
						if(field.toString().toLowerCase().indexOf("select") >=0) {
							sb.append(field.toString());
							counter++;
						}
					}
				}
			}
		}
		if (sb.length() > 0) {

			try {
				if (counter > 0) {
					writer.append("\n\n");
				}
				sourceFile = sourceFile.replace(fileRoot, "");
				sourceFile = sourceFile.replace("\\", "/");
				writer.append(sourceFile + "\n");
				String content = sb.toString();
				content = content.replace("\" +", "\"\n\t\t+ ");
				content = content.replace("\"+", "\"\n\t\t+ ");
				writer.append(content);
			}catch(IOException ioe) {

			}
		}

	}

	private void extractSql() {
		File folder = new File(fileRoot);
		List<File> poms = new ArrayList<File>();
		handleOneFolder(folder, poms);

		System.out.println("begin to analyze files of :" + poms.size());
		try {
			int index = 1;
			for(File f : poms) {

				System.out.println("begin to analyze file : " + index + " " + f.getName());
				analyzeOneFile(f.getPath(), writer);
				index++;
			}
		}
		finally {
			try {
				writer.flush();
				writer.close();
			} catch(IOException e) {

			}
		}
		System.out.println("successfully find sql count:" + counter);
	}

	private void handleOneFolder(File folder,  List<File>  poms) {
		if(!folder.isDirectory()) {
			return;
		}

		String[] files = folder.list();
		for(String oneFile : files) {
			String fullFileName = folder.getPath() + "/" + oneFile;
			if (fullFileName.endsWith(".java") && fullFileName.indexOf("src\\test\\java\\") < 0) {
				poms.add(new File(fullFileName));
				continue;
			} 
			File f = new File(fullFileName);
			if (f.isDirectory()) {
				handleOneFolder(f, poms);
			}
		}
	}

	private String getFileContent(String fName) {
		try {	
			File file = new File(fName);
			BufferedReader in = new BufferedReader(new FileReader(file));
			StringBuffer buffer = new StringBuffer(); 
			String line = null;
			while (null != (line = in.readLine())) {
				buffer.append("\t" + line);
				buffer.append("\n");
			}	

			return buffer.toString();

		}
		catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
}

 

思路也简单就是遍历 codeOfRoot 下面的所有java 文件, 找到 所有的field 定义的值里面包含 select 关键字的 field,  然后将所有这些满足条件的都写到一个log 文件。 

 

到时候将log 文件发给DBA 就行了。 当然还可以更进一步来个CI,  可以定期去扫项目的代码, 然后比较产生的log 文件的变化。 然后DBA 定期看 变化的SQL 就好了, 是不是很酷。

 

 

 

分享到:
评论

相关推荐

    基于Eclipse-JDT生成Java源代码的AST并可视化.zip

    本教程将介绍如何利用Eclipse JDT生成Java源代码的AST,并通过可视化工具进行展示。 首先,你需要安装Eclipse IDE,并且确保已经安装了JDT插件。如果你使用的是默认的Eclipse IDE安装,那么JDT通常已经包含在内。...

    JDT简单的实例(两个)

    3. **编写代码分析器**:创建一个新的Java类,如`CodeAnalyzer`,并使用JDT API来解析和检查Java源代码。例如,我们可以检查类中是否存在未使用的变量或方法。 4. **运行插件**:通过Eclipse的插件开发环境(PDE)...

    AST整理.txt学习JDT的AST相关网站和资料收集

    而AST则是Eclipse JDT中一个非常重要的概念,它是Java源代码的一种内部表示形式,可以被用来分析和修改程序结构。 ##### 2.1 AST基本概念 - **AST**:抽象语法树是一种树形的数据结构,它表示程序的语法结构。在...

    调试 ms 源代码

    对于调试MS的Java源代码,通常会使用Visual Studio Code (VS Code) 或者Eclipse等集成开发环境(IDE),它们都提供了强大的调试工具。确保你的IDE已经安装了Java和相关插件,如Java Debugger (for VS Code) 或者JDT ...

    Eclipse JDT AST使用方法(word)

    在Eclipse JDT中,AST(Abstract Syntax Tree,抽象语法树)是解析Java源代码的关键工具,它将源代码转换为一种层次化的数据结构,便于进行各种代码分析和处理。 AST的节点定位是其核心操作之一。每个ASTNode代表源...

    eclipse JDT的使用

    3. **构建工具**:JDT包含了构建工具,如Java Builder,它自动编译项目中的源代码,并在发现错误时提供反馈。此外,还有支持Ant和Maven的插件,使开发者能够轻松管理不同类型的构建过程。 4. **调试器**:Eclipse ...

    eclipse-JDT-3.3.1.zip

    1. **源代码编辑器**:Eclipse JDT提供了集成的Java源代码编辑器,支持语法高亮、自动代码完成、错误检测和快速修复,以及重构工具。这些功能极大地提高了开发效率和代码质量。 2. **构建工具**:JDT包含了一个基于...

    org.eclipse.jdt.core_3.6.0.v_A58.jar

    1. 编译器:JDT Core中的Java编译器是基于ANTLR(ANother Tool for Language Recognition)的,能够解析和理解Java源代码,生成字节码,进行类型检查和错误报告。它还支持Javadoc的生成以及遵循Java语言规范的新特性...

    ant 编译用 jdt_jars

    `ant编译用jdt_jars`指的是使用Ant进行项目构建时,利用JDT的相关库来执行编译任务。 Ant是一个开源的Java构建工具,它的主要功能包括编译源代码、打包、测试、部署等。与传统的Makefile相比,Ant使用XML来描述构建...

    JDT应用开发相关资料

    通过上述代码,可以获取到对应的Java元素,并利用JDT API进行进一步的操作,如遍历、查询模型中的信息等。此外,这些Java元素也支持对底层非Java资源的查询操作。 #### Java元素的显示与浏览 某些Java元素可以在...

    eclipse.jdt

    3. **调试工具**:Eclipse.jdt集成了强大的调试器,允许开发者在源代码级别进行断点设置、单步执行、查看变量值、调用堆栈等操作,方便问题定位和修复。 4. **项目管理**:它支持Java工程的创建、导入和导出,以及...

    Eclipse jdt 2.0 plugin developer guide

    - **描述**:介绍了如何使用API来编译Java源代码。 - **关键步骤**:设置编译环境、编译代码、处理编译错误。 #### 5.3 使用Java搜索引擎 - **描述**:讲解了如何使用搜索引擎在Java项目中查找特定类型的元素。 - *...

    java se6 全方位学习 ---源代码及附录

    在学习过程中,你可以逐个研究源代码,理解它们如何利用Java 6的新特性,同时参考附录中的解释和指导,这将有助于你全面掌握这个版本的Java编程。记得在实践中不断调试和测试,以便更好地理解和运用这些知识。

    精通Eclipse(第二版9-23章)光盘源代码

    源代码包含了从第9章到第23章的全部示例项目,旨在帮助读者通过实际操作来学习和巩固理论知识。 在Eclipse的学习中,了解和掌握以下几个关键知识点至关重要: 1. **工作空间(Workspace)管理**:Eclipse的工作...

    eclipse.jdt.doc.user.3.1.pdf.zip

    6. **Java模型和API**:介绍JDT提供的Java模型,用于访问和操作项目中的Java元素,以及如何利用JDT API进行插件开发。 7. **版本控制集成**:说明如何将Eclipse与版本控制系统(如SVN、Git等)集成,进行代码版本...

    jdt.rar_jdt-compiler.jar

    `jdt-compiler.jar`是这个工具集中的关键组件,包含了Java源代码的编译逻辑。 描述中提到的"进度条"和"动画加载的计算"可能是在讨论一个用户界面(UI)设计,其中进度条用于展示动画加载的状态。在软件开发中,特别是...

    AST解析java源文件相关jar包

    它包含了用于解析、操作和生成Java源代码的类,包括构建AST的工具。通过JDT,你可以实现诸如提取类信息、查找特定方法、分析类型关系等功能。 Javassist则是另一个流行的Java字节码操作库,它不仅可以用来动态生成...

    JDT_fundamentals

    【JDT基础知识】\n\nJava Development Tools (JDT) 是Eclipse IDE中的核心组件,专注于Java语言...同时,掌握如何利用这些工具来创建自定义的代码分析和改进工具,将极大地提升开发者在Java开发环境中的效率和专业性。

    jdt 核心知识

    5. **项目管理(Project Management)**:JDT允许开发者创建、管理和组织Java项目,包括源代码目录结构、构建路径、依赖关系等。 6. **重构(Refactoring)**:JDT提供了丰富的重构工具,如提取方法、重命名、移动...

Global site tag (gtag.js) - Google Analytics