Eclipse代码生成技术

  • 介绍
本文介绍基于Eclipse提供的API(JDT)来实现代码生成的技术。 如下图所示,可以通过Eclipse的向导(Wizard)来生成一些类,减少重复、无用的工作,提高效率。 [caption id="attachment_3879" align="aligncenter" width="525"] new_service_wizard new_service_wizard[/caption] 如果你对Eclipse插件开发感兴趣的话,可以从本站中获取到很多相关资料,也欢迎留下在阅读过程中的任何疑问,你将会得到及时的帮助!另外,本文也是“自动化开发”系列的一部分。
  • 创建package(包)
[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] 如果想知道如何做包查找以及更多资源查找的话,可以从本站中搜索相关内容。
  • 创建class(类)
[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源文件在删除之后发现还能在工程中看到,而双击打开的时候却被提示文件已经被删除)。
  • 添加method(方法)
[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]
  • 添加field(属性)
[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]
  • 添加annotation(注解)
[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]

转载于:https://my.oschina.net/surenpi/blog/816959

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值