使用javaParser抽取java依赖文件路径

该代码示例展示了如何使用javaparser库解析Java源代码,提取类的包名、类名、继承的父类、实现的接口以及导入的类。程序遍历项目源文件,构建类的继承和实现关系图,并以JSON格式输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、引入依赖  下载路径  https://download.csdn.net/download/wer754105453/87970837

        <dependency>
            <groupId>com.github.javaparser</groupId>
            <artifactId>javaparser-core</artifactId>
            <version>3.6.16</version>
            <scope>compile</scope>
        </dependency>

2、抽取代码

引入包:

import com.alibaba.fastjson.JSON;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.utils.ParserCollectionStrategy;
import com.github.javaparser.utils.ProjectRoot;


public class Test{

	public static void main(String[] args) throws Exception {
		final String filter = ".com.";
		Map<String,ClazzDesc> map = new HashMap<String,ClazzDesc>();
		List<CompilationUnit> clazzs = clazzParse();
		clazzs.forEach(clazz -> {
			if(clazz.getPackageDeclaration().isPresent()){
				String key = clazz.getPackageDeclaration().get().getName() + "." + clazz.getPrimaryTypeName().get();
				map.put(key, new DccFetchDataController().new ClazzDesc());
				
				//设置类路径
				map.get(key).setClzzResPath(clazz.getStorage().get().getPath().toString());

				
				//查找类实现的接口、父类、
				final NodeList<ClassOrInterfaceType> extendClaszzs = new NodeList<>();
				final NodeList<ClassOrInterfaceType> implClaszzs  = new NodeList<>();
				clazz.getTypes().forEach(type -> {
				if (type instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) {
					//设置是否为接口
					map.get(key).setInterface(((ClassOrInterfaceDeclaration) type).isInterface());
					extendClaszzs.addAll(((ClassOrInterfaceDeclaration) type).getExtendedTypes());
					implClaszzs.addAll(((ClassOrInterfaceDeclaration) type).getImplementedTypes());
					//else if (type instanceof com.github.javaparser.ast.body.EnumDeclaration) 
					//else if (type instanceof com.github.javaparser.ast.body.AnnotationDeclaration)
				} 
				
				//查找导入类
				clazz.getImports().forEach(importVal->{
						if (importVal.getNameAsString().contains(filter)) {
							map.get(key).getImportClazzList().add(importVal.getNameAsString());

							extendClaszzs.forEach(ext -> {
								if (importVal.getNameAsString().endsWith(ext.getNameAsString())) {
									map.get(key).setExtendsList(importVal.getNameAsString());
								}
							});

							implClaszzs.forEach(impt -> {
								if (importVal.getNameAsString().endsWith(impt.getNameAsString())) {
									map.get(key).getImplFaceList().add(importVal.getNameAsString());
								}
							});
						}
				});
			});
			}
		});
		//System.out.println(JSON.toJSONString(map));
		Set<String> set  = exportRefFile("com.xx.clasName",map,new HashSet<>(),true);
		System.out.println(JSON.toJSONString(set));
//		Runtime runtime = Runtime.getRuntime();
//		for (String filePath : set) {
//			Process process = runtime.exec("cmd.exe zip d:/2.zip "+ filePath);
//			System.out.println(process);
//		}
	}
	
	static Set<String> exportRefFile(String className, Map<String, ClazzDesc> map, Set<String> set,boolean isUp) {
		ClazzDesc clazzDesc = map.get(className);
		set.add(clazzDesc.getClzzResPath());
		if(isUp){
			String extendsClazz = clazzDesc.getExtendsList();
			List<String> implFaces = clazzDesc.getImplFaceList();
			List<String> importClazzs = clazzDesc.getImportClazzList();
			List<String> tmps = new ArrayList<>();
			//向上找父类继承,接口实现
			if (extendsClazz != null)
				tmps.add(extendsClazz);
			if (implFaces.size() > 0)
				tmps.addAll(implFaces);
			if (importClazzs.size() > 0)
				tmps.addAll(importClazzs);
			tmps.forEach(item -> {
				ClazzDesc tmp = map.get(item);
				if (tmp != null && set.add(tmp.getClzzResPath())) {
					exportRefFile(item, map, set,isUp);
				}
			});
		}
		//向下找接口实现类
		if(clazzDesc.isInterface()){
			map.forEach((key,value)->{
				 if(  ( (ClazzDesc) value).getImplFaceList().contains(className) && 
						 set.add( ((ClazzDesc) value).getClzzResPath() )){
					 exportRefFile(key, map, set,true);
					 exportRefFile(key, map, set,false);
				 }
			});
		}
		return set;
	}
	

	private static List<CompilationUnit> clazzParse() {
		Path root = Paths.get("D:/ecp_2380/bb_hb/dev/111/componentcenter");
		ProjectRoot projectRoot = new ParserCollectionStrategy().collect(root);
		List<CompilationUnit> cuList = new ArrayList<CompilationUnit>();
		projectRoot.getSourceRoots().forEach(sourceRoot -> {
			try {
				// 解析source root
				sourceRoot.tryToParse();
			} catch (IOException e) {
				e.printStackTrace();
			}
			cuList.addAll(sourceRoot.getCompilationUnits());
		});
		return cuList;
	}
	
	public class ClazzDesc{
		String extendsList;
		String clzzResPath;
		boolean isInterface;
		List<String> implFaceList = new ArrayList<String>();
		List<String> importClazzList = new ArrayList<String>();
		public ClazzDesc(){}
		public String getExtendsList() {
			return extendsList;
		}
		public void setExtendsList(String extendsList) {
			this.extendsList = extendsList;
		}
		public List<String> getImplFaceList() {
			return implFaceList;
		}
		public void setImplFaceList(List<String> implFaceList) {
			this.implFaceList = implFaceList;
		}
		public List<String> getImportClazzList() {
			return importClazzList;
		}
		public void setImportClazzList(List<String> importClazzList) {
			this.importClazzList = importClazzList;
		}
		public String getClzzResPath() {
			return clzzResPath;
		}
		public void setClzzResPath(String clzzResPath) {
			this.clzzResPath = clzzResPath;
		}
		public boolean isInterface() {
			return isInterface;
		}
		public void setInterface(boolean isInterface) {
			this.isInterface = isInterface;
		}
	}
}

 

java精神(基于函数式组合子逻辑的javaparser框架) 一。 释名。 为什么叫精神? 如果你熟悉c++,那么你可能知道一个叫做”spirit”的parser库。它利用c++的模板元编程能力,使用c++语言本身提供了一个递归下降文法解析的框架。 我这里介绍的jparsec库,就是一个java里面的递归下降文法解析框架。 不过,它并非是spirit的java版本。 Jparsec的蓝本来自Haskell语言的parsec库。Parsec是一个基于monad的parser组合子库。 这个库的目的是要在java中提供一个类似parsec, spirit的库,这种组合子库并非c++的专利,java/c#也可以做到。这个库还将在java5.0上被改写,类型安全上它将也不再逊色于c++。 那么,为什么叫“函数式”呢?java是面向对象的嘛。 如果你使用过haskell, lisp等语言,这个函数式不用解释你也知道是怎么回事了。 如果你是一个老牌的c++/java程序员,那么这里还要稍微解释一下。当然如果您对这些虚头八脑的名词不感兴趣,那么,你尽可以跳过这一章,不知道什么是“函数式”,并不会影响你对这个库的理解的。 C++这几年随着gp的普及,“函数式”这个老孔乙己逐渐又被人从角落里面拽了出来。一个c++程序员所熟悉的“函数式”很可能是stl的for_each, transform,count_if这些函数。 怎么说呢,就象我不能否定str.length()这个调用属于OO一样,我也无法说for_each, transform不是函数式。 但是,“函数式”的精髓不在于此。 一般归纳起来,就像我们说OO是什么多态,封装,继承一样,“函数式”的特征被总结为: 1。无副作用。 2。高阶函数。 3。延迟计算 而最最有意义的(至少我认为如此),是基于高阶函数的函数组合能力。一些人把这叫做glue。 简短地说,什么让函数式编程如此强大?是用简单的函数组合出复杂函数的能力。 我可以想象,说到这里,你还是一头雾水。“什么是组合?1+1不是也把两个1组合成2了吗?new A(new B(), new C())不也是从B和C组合成A了?”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值