本文介绍基于Eclipse提供的API(JDT)来实现代码生成的技术。 如下图所示,可以通过Eclipse的向导(Wizard)来生成一些类,减少重复、无用的工作,提高效率。 [caption id="attachment_3879" align="aligncenter" width="525"]
![new_service_wizard](https://static.oschina.net/uploads/img/201612/31204917_mfcN.png)
new_service_wizard[/caption] 如果你对Eclipse插件开发感兴趣的话,可以从本站中获取到很多相关资料,也欢迎留下在阅读过程中的任何疑问,你将会得到及时的帮助!另外,本文也是“自动化开发”系列的一部分。
[codesyntax lang="java"]
if(monitor == null) {
monitor = new NullProgressMonitor();
}
IPackageFragmentRoot packageFragmentRoot = null;
try {
for(IPackageFragmentRoot root : project.getPackageFragmentRoots()) {
if(root.getKind() == 1) {
packageFragmentRoot = root;
break;
}
}
} catch (JavaModelException e) {
Logger.error("查找PackageFragmentRoot错误!", e);
}
mkPackages(packageFragmentRoot, servicePackage, monitor);
/**
* 如果包不存在的话就创建
* @param root
* @param packageFragment
* @param monitor
*/
private void mkPackages(IPackageFragmentRoot root, String packageFragment, IProgressMonitor monitor) {
if(root == null) {
return;
}
monitor.subTask("make sure the package is exists! package : " + packageFragment);
IPackageFragment pk = root.getPackageFragment(packageFragment);
if(pk == null || !pk.exists()) {
try {
pk = root.createPackageFragment(packageFragment, true, monitor);
pk.save(monitor, true);
} catch (JavaModelException e) {
Logger.error("创建包失败!", e);
}
}
}
[/codesyntax] 如果想知道如何做包查找以及更多资源查找的话,可以从本站中搜索相关内容。
[codesyntax lang="java"]
public static ICompilationUnit createCompilationUnit(IJavaProject project, String type, String packageName, String typeName, String superCls, String ...superInters) {
IPackageFragmentRoot packageFragmentRoot = project.getPackageFragmentRoot("java");
IPackageFragmentRoot[] roots;
try {
roots = project.getPackageFragmentRoots();
packageFragmentRoot = roots[0];
} catch (JavaModelException e) {
Logger.error("", e);
}
IPackageFragment packageFragment = packageFragmentRoot.getPackageFragment(packageName);
try {
ICompilationUnit unit = packageFragment.createCompilationUnit(typeName + ".java", "", false, null);
unit.becomeWorkingCopy(null);
IBuffer buffer = unit.getBuffer();
String simpleTypeStub = constructSimpleTypeStub(type, typeName, superCls, superInters);
String lineDelimiter = System.getProperty("line.separator", "\n");
String cuContent = constructCUContent(unit, simpleTypeStub, lineDelimiter);
buffer.setContents(cuContent);
return unit;
} catch (JavaModelException e) {
Logger.error("", e);
} catch (CoreException e) {
Logger.error("", e);
}
return 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();
}
public static String constructCUContent(ICompilationUnit cu, String typeContent, String lineDelimiter) 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(8);
parser.setProject(cu.getJavaProject());
parser.setSource(content.toCharArray());
CompilationUnit unit = (CompilationUnit) parser.createAST(null);
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();
}
/**
* 提交修改内容
* @param cUnit
* @param force
* @param monitor
* @throws JavaModelException
*/
public static void commitCompilationUnit(ICompilationUnit cUnit,
boolean force, IProgressMonitor monitor) throws JavaModelException {
cUnit.reconcile(0, false, null, monitor);
cUnit.commitWorkingCopy(force, monitor);
}
[/codesyntax] 这里有个地方需要注意:上面的代码中使用方法becomeWorkingCopy创建了一份源代码副本,在对源文件修改完之后需要将副本丢弃(discardWorkingCopy),不然的话副本会一直在工程中存在,从而导致一些不可见的情况发生(例如:生成的Java源文件在删除之后发现还能在工程中看到,而双击打开的时候却被提示文件已经被删除)。
[codesyntax lang="java"]
/**
* 给属性添加getter方法
* @param attrType
* @param name
* @return
* @throws CoreException
*/
public IMethod addGetter(String attrType, String name) throws CoreException{
String shortAttrType = OperatorUtil.getShortClass(attrType);
String content = CodeGeneration.getGetterMethodBodyContent(
type.getCompilationUnit(),
type.getTypeQualifiedName('.'),
"", name, "\n");
StringBuffer buf = new StringBuffer();
buf.append(PUBLIC).append(" ");
buf.append(shortAttrType);
buf.append(" get").append(name.substring(0, 1).toUpperCase()).append(name.substring(1));
buf.append("(){\n");
buf.append(content);
buf.append("\n}");
if(!shortAttrType.equals(attrType)){
importsMgr.addImport(attrType);
}
IMethod method = type.createMethod(buf.toString(), null, false, null);
return method;
}
[/codesyntax]
[codesyntax lang="java"]
/**
* 添加属性
* @param access
* @param fieldType
* @param name
* @return
* @throws JavaModelException
*/
public IField addField(String access, String fieldType, String name) throws JavaModelException{
String shortFieldType = OperatorUtil.getShortClass(fieldType);
StringBuffer buf = new StringBuffer();
buf.append("\t");
buf.append(access);
buf.append(" ");
buf.append(shortFieldType);
buf.append(" ");
buf.append(name);
buf.append(";");
if(!shortFieldType.equals(fieldType)){
importsMgr.addImport(fieldType);
}
return type.createField(buf.toString(), null, false, null);
}
[/codesyntax]
[codesyntax lang="java"]
/**
* 添加注解。建议再一个元素上调用一次,不然可能会有问题。
* @param member 要添加注解的类成员,当改值为null时则就是给类上添加注解
* @param buf 注解内容
* @throws JavaModelException
*/
public void addAnnotation(IMember member, StringBuffer buf) throws JavaModelException {
if(member == null) {
member = type;
}
ISourceRange range = member.getSourceRange();
ISourceRange docRange = member.getJavadocRange();
IBuffer typeBuf = type.getCompilationUnit().getBuffer();
int typeOffset = range.getOffset();
int typeLength = range.getLength();
if(docRange != null){
int docRangeLength = 0;
docRangeLength = docRange.getLength();
typeOffset += docRangeLength;
typeLength -= docRangeLength;
}
buf.append(typeBuf.getText(typeOffset, typeLength));
typeBuf.replace(typeOffset, typeLength, buf.toString());
}
[/codesyntax]
- 添加comment(注释)
- 添加import(导入)
[codesyntax lang="java"]
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.ui.CodeStyleConfiguration;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.UndoEdit;
/**
* @author surenpi.com
* @since jdk1.6
* 2016年3月4日
*/
public class ImportManager {
private ImportRewrite importRewrite;
public ImportManager(CompilationUnit astRoot) {
importRewrite = CodeStyleConfiguration.createImportRewrite(astRoot, true);
}
public void addImport(String qualifiedTypeName) {
importRewrite.addImport(qualifiedTypeName);
}
public UndoEdit create(IProgressMonitor monitor) throws CoreException {
TextEdit edit = importRewrite.rewriteImports(monitor);
return importRewrite.getCompilationUnit().applyTextEdit(edit, monitor);
}
}
[/codesyntax] 上面是对import操作的封装,下面是使用例子: [codesyntax lang="java"]
private static CompilationUnit createASTForImports(ICompilationUnit cu) {
ASTParser parser = ASTParser.newParser(8);
parser.setSource(cu);
parser.setResolveBindings(true);
parser.setFocalPosition(0);
return (CompilationUnit) parser.createAST(null);
}
public static ImportManager createImportManager(ICompilationUnit cUnit) {
CompilationUnit astRoot = createASTForImports(cUnit);
return new ImportManager(astRoot);
}
importMgr.addImport("java.util.Date");
importMgr.create(monitor);
[/codesyntax]
[codesyntax lang="java"]
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ILocalVariable;
/**
* 根据IMethod来获取方法头,例如:
* public void getMethodHeader(IMethod method, StringBuffer buf)
* @param method
* @param buf
* @throws JavaModelException
* @throws IllegalArgumentException
*/
public void getMethodHeader(IMethod method, StringBuffer buf)
throws IllegalArgumentException, JavaModelException {
if(method == null || buf == null) {
return;
}
buf.append("public ");
buf.append(Signature.toString(method.getReturnType()));
buf.append(" ");
buf.append(method.getElementName());
buf.append("(");
for(ILocalVariable param : method.getParameters()) {
buf.append(Signature.toString(param.getTypeSignature()));
buf.append(" ");
buf.append(param.getElementName());
}
buf.append(")");
}
[/codesyntax]