JDT(Java Development Tools)是Eclipse中有关Java开发的一个组件,该组件中封装了大多数Java开发中的功能,也可以说它是Eclipse支持Java开发的核心组件。 本文将会介绍到:AST(Abstract Syntax Tree)、IProject、IJavaProject、IType等内容。 想了解更多Eclipse中的组件,可以在本站中搜索“Eclipse框架下的组件”。 下面先对几个重要的接口进行介绍。
JDT组件使用AST将Java中的对象(接口、类、方法、属性等)建立了一系列的模型。通过AST可以把Java对象当做一个树,用访问节点的方式来修改。
[caption id="attachment_4314" align="aligncenter" width="217"]
![ijavaelement_tree](https://static.oschina.net/uploads/img/201612/31204440_QjvS.png)
ijavaelement_tree[/caption] 从上图中可以看到org.eclipse.jdt.core.IJavaElement接口是所有Java对象模型中的父,而且JDT中包含了所有的Java对象。 IType代表一个类 IMethod代表一个方法 IAnnotation代表一个注解 下面是一个可以创建一个Java类型的例子: [codesyntax lang="java"]
/**
* 创建一个类(class)或者接口(interface)
* @param project 工程对象
* @param type 应当是class、interface或者enum
* @param packageName 包名
* @param typeName 应当是Java源文件名称但不包含后缀,例如:Test.java就应该是Test
* @param superCls 父类
* @param superInters 接口列表
* @return
*/
public static ICompilationUnit createCompilationUnit(IJavaProject project, String type,
String packageName, String typeName, IProgressMonitor monitor, String superCls, String ...superInters) {
IPackageFragmentRoot packageFragmentRoot = null;
ICompilationUnit unit = null;
try {
//先查找当前工程中是否已经有了给类型
IType targetType = project.findType(packageName, typeName, monitor);
if(targetType != null){
unit = targetType.getCompilationUnit();
}
} catch (JavaModelException e) {
Logger.error(e.getMessage(), e);
}
try {
if(unit == null){
try {
//查找可以用于创建Java类型的包
IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
for(IPackageFragmentRoot root : roots){
if(root.isReadOnly() || root.isArchive() || root.isExternal()){
continue;
}
packageFragmentRoot = root;
break;
}
} catch (JavaModelException e) {
Logger.error(e.getMessage(), e);
}
IPackageFragment packageFragment = packageFragmentRoot.getPackageFragment(packageName);
//创建一个内容为空的Java类型
unit = packageFragment.createCompilationUnit(String.format("%s.java", typeName), "", false, monitor);
}
unit.becomeWorkingCopy(monitor); //先把当前编译对象变为副本
IBuffer buffer = unit.getBuffer();
String simpleTypeStub = constructSimpleTypeStub(type, typeName, superCls, superInters);
String lineDelimiter = System.getProperty("line.separator", "\n");
String cuContent = constructCUContent(unit, simpleTypeStub, lineDelimiter, monitor);
buffer.setContents(cuContent);
return unit;
} catch (JavaModelException e) {
Logger.error(String.format("创建Java过程失败,详细信息[%s]。", e.getMessage()), e);
} catch (CoreException e) {
Logger.error(e.getMessage(), e);
}
return unit;
}
public static String constructSimpleTypeStub(String typeName) {
return constructSimpleTypeStub("class", typeName, null);
}
public static String constructSimpleTypeStub(String type, String typeName, String superCls, String ...superInters) {
StringBuffer buf = new StringBuffer("public ");
buf.append(type);
buf.append(" ");
buf.append(typeName);
if(StringUtil.isNotEmpty(superCls)) {
buf.append(" extends ");
buf.append(superCls);
}
if(superInters != null && superInters.length > 0) {
buf.append(" implements");
for(String superInter : superInters) {
buf.append(" ");
buf.append(superInter);
}
}
buf.append("{\n}");
return buf.toString();
}
/**
* 构建Java类型的具体文件内容
* @param cu
* @param typeContent
* @param lineDelimiter
* @return
* @throws CoreException
*/
public static String constructCUContent(ICompilationUnit cu, String typeContent, String lineDelimiter,
IProgressMonitor monitor) throws CoreException {
String fileComment = "";// getFileComment(cu, lineDelimiter);
String typeComment = "";// getTypeComment(cu, lineDelimiter);
IPackageFragment pack = (IPackageFragment) cu.getParent();
String content = CodeGeneration.getCompilationUnitContent(cu, fileComment, typeComment, typeContent, lineDelimiter);
if (content != null) {
ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setProject(cu.getJavaProject());
parser.setSource(content.toCharArray());
CompilationUnit unit = (CompilationUnit) parser.createAST(monitor);
if (((pack.isDefaultPackage()) || (unit.getPackage() != null)) && (!unit.types().isEmpty())) {
return content;
}
}
StringBuffer buf = new StringBuffer();
if (!pack.isDefaultPackage()) {
buf.append("package ").append(pack.getElementName()).append(';');
}
buf.append(lineDelimiter).append(lineDelimiter);
if (typeComment != null) {
buf.append(typeComment).append(lineDelimiter);
}
buf.append(typeContent);
return buf.toString();
}
[/codesyntax]
IPackageFragment createPackageFragment(String name, boolean force, IProgressMonitor monitor)throws JavaModelException; 该方法可以创建一个包(package),创建完之后需要调用接口IPackageFragment的保存(save)方法。
[caption id="attachment_4316" align="aligncenter" width="300"]
![iparent_tree](https://static.oschina.net/uploads/img/201612/31204441_Srqi.png)
iparent_tree[/caption] 从上图中可以看到org.eclipse.jdt.core.IJavaProject并不是接口org.eclipse.core.resources.IProject的子接口,这一点一定要注意——IJavaProject和IProject是包含关系。
[caption id="attachment_4317" align="aligncenter" width="300"]
![icontainer_tree](https://static.oschina.net/uploads/img/201612/31204441_xjOt.png)
icontainer_tree[/caption] 从上图中可以看到,在Eclipse中文件夹(IFolder)和工程(IProject)以及工作空间(IWorkspaceRoot)是同等级的,都是属于容器(容器也是一种资源)。
[caption id="attachment_4315" align="aligncenter" width="300"]
![iresource_tree](https://static.oschina.net/uploads/img/201612/31204441_QM3y.png)
iresource_tree[/caption] org.eclipse.core.resources.IResource接口是Eclipse中所有资源(文件、文件夹、工程、workspace等)的父。
project.refreshLocal(IResource.DEPTH_INFINITE, monitor); 该方法可以刷新当前工程 未完待续。。。