Java ÄÚµå Á¶ÀÛ

Ç÷¯±×ÀÎÀº JDT API¸¦ »ç¿ëÇÏ¿© Ŭ·¡½º³ª ÀÎÅÍÆäÀ̽º¸¦ ÀÛ¼ºÇÏ°í ±âÁ¸ À¯Çü¿¡ ¸Þ¼Òµå¸¦ Ãß°¡Çϰųª À¯Çü¿¡ ´ëÇÑ ¸Þ¼Òµå¸¦ º¯°æÇÒ ¼ö ÀÖ½À´Ï´Ù.

Java ¿ÀºêÁ§Æ®¸¦ º¯°æÇÏ´Â °¡Àå °£´ÜÇÑ ¹æ¹ýÀº Java ¿ä¼Ò API¸¦ »ç¿ëÇÏ´Â °ÍÀÔ´Ï´Ù. º¸´Ù ÀϹÝÀûÀÎ ±â¼úÀÌ Java ¿ä¼ÒÀÇ ¿ø½Ã ¼Ò½º Äڵ忡 ´ëÇÑ ÀÛ¾÷À» À§ÇØ »ç¿ëµÉ ¼ö ÀÖ½À´Ï´Ù.

Java ¿ä¼Ò¸¦ »ç¿ëÇÑ ÄÚµå ¼öÁ¤

ÄÄÆÄÀÏ ´ÜÀ§ »ý¼º

ÄÄÆÄÀÏ ´ÜÀ§¸¦ ÇÁ·Î±×·¥¿¡ µû¶ó »ý¼ºÇÏ´Â °¡Àå °£´ÜÇÑ ¹æ¹ýÀº IPackageFragment.createCompilationUnitÀ» »ç¿ëÇÏ´Â °ÍÀÔ´Ï´Ù. ÄÄÆÄÀÏ ´ÜÀ§ÀÇ À̸§°ú ÄÁÅÙÃ÷¸¦ ÁöÁ¤ÇÕ´Ï´Ù. ÄÄÆÄÀÏ ´ÜÀ§°¡ ÆÐŰÁö ³»¿¡ ÀÛ¼ºµÇ°í »õ ICompilationUnitÀÌ ¸®Åϵ˴ϴÙ.

º¸Åë ÄÄÆÄÀÏ ´ÜÀ§´Â ÆÐŰÁö µð·ºÅ丮¿¡ ÇØ´çÇÏ´Â ÀûÀýÇÑ Æú´õ¿¡ È®ÀåÀÚ°¡ ".java"ÀÎ ÆÄÀÏ ÀÚ¿øÀ» ¸¸µé¾î¼­ ÀÛ¼ºµË´Ï´Ù. ÀÏ¹Ý ÀÚ¿ø API¸¦ »ç¿ëÇϸé Java µµ±¸ÀÇ µÚ·Î À̵¿ÇϹǷΠÀÏ¹Ý ÀÚ¿ø º¯°æ ¸®½º³Ê°¡ ¾Ë·ÁÁö°í JDT ¸®½º³Ê°¡ Java ¸ðµ¨À» »õ ÄÄÆÄÀÏ ´ÜÀ§·Î °»½ÅÇØ¾ß Java ¸ðµ¨ÀÌ °»½ÅµË´Ï´Ù.

ÄÄÆÄÀÏ ´ÜÀ§ ¼öÁ¤

Java ¼Ò½º¸¦ ¼öÁ¤ÇÏ´Â °¡Àå °£´ÜÇÑ ¹æ¹ýÀº Java ¿ä¼Ò API¸¦ »ç¿ëÇÏ´Â °ÍÀÔ´Ï´Ù.

¿¹¸¦ µé¾î, ÄÄÆÄÀÏ ´ÜÀ§¿¡¼­ À¯ÇüÀ» Á¶È¸ÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÏ´Ü ITypeÀ» °¡Áö¸é, À¯ÇüÀ¸·Î ¼Ò½º ÄÚµå ±¸¼º¿øÀ» Ãß°¡Çϱâ À§ÇØ createField, createInitializer, createMethod, ¶Ç´Â createType¿Í °°Àº ÇÁ·ÎÅäÄÝÀ» »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. ±¸¼º¿øÀÇ À§Ä¡¿¡ °üÇÑ Á¤º¸¿Í ¼Ò½º Äڵ尡 ÀÌ·¯ÇÑ ¸Þ¼Òµå¿¡ Á¦°øµË´Ï´Ù.

ISourceManipulation ÀÎÅÍÆäÀ̽º´Â Java ¿ä¼ÒÀÇ °øÅë ¼Ò½º Á¶ÀÛÀ» Á¤ÀÇÇÕ´Ï´Ù. ¿©±â¿¡´Â À¯Çü ±¸¼º¿øÀÇ À̸§ ¹Ù²Ù±â, À̵¿, º¹»ç ¶Ç´Â »èÁ¦ ¸Þ¼Òµå°¡ Æ÷ÇԵ˴ϴÙ.

ÀÛ¾÷ »çº»

ÄÚµå´Â ÄÄÆÄÀÏ ´ÜÀ§¸¦ Á¶ÀÛÇÏ¿© ¼öÁ¤µÇ°Å³ª(¼û°ÜÁø IFileÀÌ ¼öÁ¤µÊ), ÀÛ¾÷ »çº»À¸·Î ºÒ¸®¿ì´Â ÄÄÆÄÀÏ ´ÜÀ§ÀÇ ¸Þ¸ð¸®³» »çº»À» ¼öÁ¤ÇÒ ¼ö ÀÖ½À´Ï´Ù.

ÀÛ¾÷ »çº»Àº getWorkingCopy ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© ÄÄÆÄÀÏ ´ÜÀ§¿¡¼­ ¾òÀ» ¼ö ÀÖ½À´Ï´Ù. (ÀÛ¾÷ »çº»À» ÀÛ¼ºÇϱâ À§ÇØ ÄÄÆÄÀÏ ´ÜÀ§°¡ Java ¸ðµ¨¿¡ Á¸ÀçÇØ¾ß ÇÏ´Â °ÍÀº ¾Æ´Õ´Ï´Ù.) ÀÌ·¯ÇÑ ÀÛ¾÷ »çº»À» ÀÛ¼ºÇÑ »ç¿ëÀÚ°¡ ´©±¸ÀÌµç ´õ ÀÌ»ó ÇÊ¿äÇÏÁö ¾ÊÀ» ¶§´Â discardWorkingCopy ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© À̸¦ ¹ö·Á¾ß Çϴ åÀÓÀÌ ÀÖ½À´Ï´Ù.

ÀÛ¾÷ »çº»Àº ¸Þ¸ð¸® ³» ¹öÆÛ¸¦ ¼öÁ¤ÇÕ´Ï´Ù. getWorkingCopy() ¸Þ¼Òµå°¡ ±âº» ¹öÆÛ¸¦ ÀÛ¼ºÇÏÁö¸¸ Ŭ¶óÀÌ¾ðÆ®´Â getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor) ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© ÀÚ½ÅÀÇ ¹öÆÛ ±¸ÇöÀ» Á¦°øÇÒ ¼ö ÀÖ½À´Ï´Ù. Ŭ¶óÀÌ¾ðÆ®´Â ÀÌ ¹öÆÛÀÇ ÅØ½ºÆ®¸¦ Á÷Á¢ Á¶ÀÛÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÌ·¯ÇÑ °æ¿ì, Ŭ¶óÀÌ¾ðÆ®´Â reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor) ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© ¶§¶§·Î ¹öÆÛ¿Í ÀÛ¾÷ »çº»À» µ¿±âÈ­ÇØ¾ß ÇÕ´Ï´Ù.

¸¶Áö¸·À¸·Î, ÀÛ¾÷ »çº»Àº commitWorkingCopy ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© µð½ºÅ©¿¡ ÀúÀåµÉ ¼ö ÀÖ½À´Ï´Ù(¿ø·¡ ÄÄÆÄÀÏ ´ÜÀ§¸¦ ´ëüÇÔ).   

¿¹¸¦ µé¾î, ´ÙÀ½ ÄÚµå ½º´ÏÆêÀº »ç¿ëÀÚ ÀÛ¾÷ »çº» ¼ÒÀ¯ÀÚ¸¦ »ç¿ëÇÏ¿© ÄÄÆÄÀÏ ´ÜÀ§¿¡¼­ ÀÛ¾÷ »çº»À» ÀÛ¼ºÇÕ´Ï´Ù. ½º´ÏÆêÀ» ¹öÆÛ¸¦ ¼öÁ¤ÇÏ°í º¯°æ»çÇ×À» Á¶Á¤Çϸç, µð½ºÅ©¿¡ ´ëÇÑ º¯°æ»çÇ×À» È®¾àÇÑ ÈÄ ¸¶Áö¸·¿¡´Â ÀÛ¾÷ »çº»À» ¹ö¸³´Ï´Ù.

    // Get original compilation unit
    ICompilationUnit originalUnit = ...;
    
    // Get working copy owner
    WorkingCopyOwner owner = ...;
    
    // Create working copy
    ICompilationUnit workingCopy = originalUnit.getWorkingCopy(owner, null, null);
    
    // Modify buffer and reconcile
    IBuffer buffer = ((IOpenable)workingCopy).getBuffer();
    buffer.append("class X {}");
    workingCopy.reconcile(NO_AST, false, null, null);
    
    // Commit changes
    workingCopy.commitWorkingCopy(false, null);
    
    // Destroy working copy
    workingCopy.discardWorkingCopy();

ÀÛ¾÷ »çº»Àº ÀÛ¾÷ »çº» ¼ÒÀ¯ÀÚ¸¦ »ç¿ëÇÏ¿© ¿©·¯ Ŭ¶óÀÌ¾ðÆ®¿¡ ÀÇÇØ °øÀ¯µÉ ¼öµµ ÀÖ½À´Ï´Ù. ÀÛ¾÷ »çº»Àº ³ªÁß¿¡ findWorkingCopy ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© °Ë»öµÉ ¼ö ÀÖ½À´Ï´Ù. ±×·¯¹Ç·Î °øÀ¯ ÀÛ¾÷ »çº»Àº ¿ø·¡ ÄÄÆÄÀÏ ´ÜÀ§¿Í ÀÛ¾÷ »çº» ¼ÒÀ¯ÀÚ¿¡ ¸ÂÃç Á¶Á¤µË´Ï´Ù.

´ÙÀ½Àº Ŭ¶óÀÌ¾ðÆ® 1ÀÌ °øÀ¯ ÀÛ¾÷ »çº»À» ÀÛ¼ºÇϰí, Ŭ¶óÀÌ¾ðÆ® 2°¡ ÀÌ ÀÛ¾÷ »çº»À» °Ë»öÇϸç, Ŭ¶óÀÌ¾ðÆ® 1ÀÌ ÀÛ¾÷ »çº»À» ¹ö¸° ÈÄ, ÀÌ °øÀ¯ ÀÛ¾÷ »çº» °Ë»öÀ» ½ÃµµÇϴ Ŭ¶óÀÌ¾ðÆ® 2°¡ ÀÛ¾÷ »çº»ÀÌ ´õ ÀÌ»ó Á¸ÀçÇÏÁö ¾ÊÀ½À» ¾Ë¸®´Â ¹æ¹ýÀ» º¸¿©ÁÝ´Ï´Ù.

    // Client 1 & 2: Get original compilation unit
    ICompilationUnit originalUnit = ...;
    
    // Client 1 & 2: Get working copy owner
    WorkingCopyOwner owner = ...;
    
    // Client 1: Create shared working copy
    ICompilationUnit workingCopyForClient1 = originalUnit.getWorkingCopy(owner, null, null);
    
    // Client 2: Retrieve shared working copy
    ICompilationUnit workingCopyForClient2 = originalUnit.findWorkingCopy(owner);
     
    // This is the same working copy
    assert workingCopyForClient1 == workingCopyForClient2;
    
    // Client 1: Discard shared working copy
    workingCopyForClient1.discardWorkingCopy();
    
    // Client 2: Attempt to retrieve shared working copy and find out it's null
    workingCopyForClient2 = originalUnit.findWorkingCopy(owner);
    assert workingCopyForClient2 == null;

DOM/AST API¸¦ »ç¿ëÇÑ ÄÚµå ¼öÁ¤

CompilationUnit¸¦ ÀÛ¼ºÇÏ´Â ¼¼ °¡Áö ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ù°, ASTParser¸¦ »ç¿ëÇÕ´Ï´Ù. µÑ°, ICompilationUnit#reconcile(...)À» »ç¿ëÇÕ´Ï´Ù. ¼¼Â°, AST(Abstract Syntax Tree) ÆÑÅ丮 ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© ½ºÅ©·¡Ä¡¿¡¼­ ½ÃÀÛÇÕ´Ï´Ù.

±âÁ¸ ¼Ò½º Äڵ忡¼­ AST ÀÛ¼º

ASTParserÀÇ ÀνºÅϽº´Â ASTParser.newParser(int)¿¡ ÀÇÇØ ÀÛ¼ºµÇ¾î¾ß ÇÕ´Ï´Ù.

¼Ò½º ÄÚµå´Â ´ÙÀ½ ¸Þ¼Òµå Áß Çϳª¿¡ ÀÇÇØ ASTParser¿¡ Á¦°øµË´Ï´Ù. ±×·± ´ÙÀ½ createAST(IProgressMonitor)¸¦ È£ÃâÇÏ¿© AST¸¦ ÀÛ¼ºÇÕ´Ï´Ù.

°¢ ³ëµå¿¡ ´ëÇÑ ¿Ã¹Ù¸¥ ¼Ò½º À§Ä¡¿Í ÇÔ²² AST°¡ »ý¼ºµË´Ï´Ù. Æ®¸®°¡ ÀÛ¼ºµÇ±â Àü¿¡ setResolveBindings(boolean)¿¡ ÀÇÇØ ¹ÙÀεù ºÐ¼®ÀÌ ¿äûµÇ¾î¾ß ÇÕ´Ï´Ù. ¹ÙÀεù ÇØ°áÀº ºñ¿ëÀÌ µå´Â Á¶ÀÛÀ̸ç ÇÊ¿ä ½Ã¿¡¸¸ ¼öÇàµÇ¾î¾ß ÇÕ´Ï´Ù. Æ®¸®°¡ ¼öÁ¤µÇ¸é ¹Ù·Î ¸ðµç À§Ä¡ ¹× ¹ÙÀεùÀÌ ¼Õ½ÇµË´Ï´Ù.

ÀÛ¾÷ »çº»À» Á¶Á¤ÇÏ¿© AST ÀÛ¼º

ÀÛ¾÷ »çº»ÀÌ ÀÏÄ¡ÇÏÁö ¾ÊÀº °æ¿ì(¼öÁ¤µÈ °æ¿ì) reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor) ¸Þ¼Òµå¸¦ È£ÃâÇÏ¿© AST¸¦ ÀÛ¼ºÇÒ ¼ö ÀÖ½À´Ï´Ù. AST ÀÛ¼ºÀ» ¿äûÇÏ·Á¸é AST.JLS2¸¦ ù ¹øÂ° ¸Å°³º¯¼ö·Î »ç¿ëÇÏ¿© reconcile(...)À» ¸Þ¼Òµå¸¦ È£ÃâÇϽʽÿÀ.

¹®Á¦Á¡ ¿äûÀÚ°¡ Ȱ¼ºÀ̰ųª ¹®Á¦Á¡ ¹ß°ßÀÌ °­Á¦ ½ÇÇàµÈ °æ¿ì¿¡¸¸ ¹ÙÀεùÀÌ °è»êµË´Ï´Ù. ¹ÙÀεù ÇØ°áÀº ºñ¿ëÀÌ µå´Â Á¶ÀÛÀ̸ç ÇÊ¿ä ½Ã¿¡¸¸ ¼öÇàµÇ¾î¾ß ÇÕ´Ï´Ù. Æ®¸®°¡ ¼öÁ¤µÇ¸é ¹Ù·Î ¸ðµç À§Ä¡ ¹× ¹ÙÀεùÀÌ ¼Õ½ÇµË´Ï´Ù.

½ºÅ©·¡Ä¡¿¡¼­

AST ÆÑÅ丮 ¸Þ¼Òµå¸¦ »ç¿ëÇÏ¿© ½ºÅ©·¡Ä¡¿¡¼­ CompilationUnit¸¦ ÀÛ¼ºÇÏ´Â °ÍÀÌ °¡´ÉÇÕ´Ï´Ù. ÀÌ ¸Þ¼Òµå À̸§Àº new...·Î ½ÃÀ۵˴ϴÙ. ´ÙÀ½Àº HelloWorld Ŭ·¡½º ÀÛ¼ºÀÇ ¿¹ÀÔ´Ï´Ù.

ù ¹øÂ° ½º´ÏÆêÀº »ý¼ºµÈ Ãâ·ÂÀÔ´Ï´Ù.

	package example;
	import java.util.*;
	public class HelloWorld {
		public static void main(String[] args) {
			System.out.println("Hello" + " world");
		}
	}

´ÙÀ½ ½º´ÏÆêÀº Ãâ·ÂÀ» »ý¼ºÇÑ ÇØ´ç ÄÚµåÀÔ´Ï´Ù.

		AST ast = new AST();
		CompilationUnit unit = ast.newCompilationUnit();
		PackageDeclaration packageDeclaration = ast.newPackageDeclaration();
		packageDeclaration.setName(ast.newSimpleName("example"));
		unit.setPackage(packageDeclaration);
		ImportDeclaration importDeclaration = ast.newImportDeclaration();
		QualifiedName name = 
			ast.newQualifiedName(
				ast.newSimpleName("java"),
				ast.newSimpleName("util"));
		importDeclaration.setName(name);
		importDeclaration.setOnDemand(true);
		unit.imports().add(importDeclaration);
		TypeDeclaration type = ast.newTypeDeclaration();
		type.setInterface(false);
		type.setModifiers(Modifier.PUBLIC);
		type.setName(ast.newSimpleName("HelloWorld"));
		MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
		methodDeclaration.setConstructor(false);
		methodDeclaration.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
		methodDeclaration.setName(ast.newSimpleName("main"));
		methodDeclaration.setReturnType(ast.newPrimitiveType(PrimitiveType.VOID));
		SingleVariableDeclaration variableDeclaration = ast.newSingleVariableDeclaration();
		variableDeclaration.setModifiers(Modifier.NONE);
		variableDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newSimpleName("String"))));
		variableDeclaration.setName(ast.newSimpleName("args"));
		methodDeclaration.parameters().add(variableDeclaration);
		org.eclipse.jdt.core.dom.Block block = ast.newBlock();
		MethodInvocation methodInvocation = ast.newMethodInvocation();
		name = 
			ast.newQualifiedName(
				ast.newSimpleName("System"),
				ast.newSimpleName("out"));
		methodInvocation.setExpression(name);
		methodInvocation.setName(ast.newSimpleName("println")); 
		InfixExpression infixExpression = ast.newInfixExpression();
		infixExpression.setOperator(InfixExpression.Operator.PLUS);
		StringLiteral literal = ast.newStringLiteral();
		literal.setLiteralValue("Hello");
		infixExpression.setLeftOperand(literal);
		literal = ast.newStringLiteral();
		literal.setLiteralValue(" world");
		infixExpression.setRightOperand(literal);
		methodInvocation.arguments().add(infixExpression);
		ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);
		block.statements().add(expressionStatement);
		methodDeclaration.setBody(block);
		type.bodyDeclarations().add(methodDeclaration);
		unit.types().add(type);

Ãß°¡ À§Ä¡ °Ë»ö

DOM/AST ³ëµå´Â ÇÑ ½ÖÀÇ À§Ä¡¸¸À» Æ÷ÇÔÇÕ´Ï´Ù(½ÃÀÛ À§Ä¡ ¹× ³ëµåÀÇ ±æÀÌ). À̰ÍÀÌ Ç×»ó ÃæºÐÇÏÁö´Â ¾Ê½À´Ï´Ù. Áß°£ À§Ä¡¸¦ °Ë»öÇÏ·Á¸é, IScanner API°¡ »ç¿ëµÇ¾î¾ß ÇÕ´Ï´Ù. ¿¹¸¦ µé¾î, instanceof ¿¬»êÀÚÀÇ À§Ä¡¸¦ ¾Ë±â À§ÇØ InstanceofExpressionÀ» °¡Áý´Ï´Ù. À̰ÍÀ» ¼öÇàÇϱâ À§ÇØ ´ÙÀ½ ¸Þ¼Òµå¸¦ ÀÛ¼ºÇÒ ¼ö ÀÖ½À´Ï´Ù.
	private int[] getOperatorPosition(Expression expression, char[] source) {
		if (expression instanceof InstanceofExpression) {
			IScanner scanner = ToolFactory.createScanner(false, false, false, false);
			scanner.setSource(source);
			int start = expression.getStartPosition();
			int end = start + expression.getLength();
			scanner.resetTo(start, end);
			int token;
			try {
				while ((token = scanner.getNextToken()) != ITerminalSymbols.TokenNameEOF) {
					switch(token) {
						case ITerminalSymbols.TokenNameinstanceof:
							return new int[] {scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition()};
					}
				}
			} catch (InvalidInputException e) {
			}
		}
		return null;
	}
IScanner´Â ÅäÅ«À¸·Î ÀÔ·Â ¼Ò½º¸¦ ³ª´©´Â µ¥ »ç¿ëµË´Ï´Ù. °¢ ÅäÅ«Àº ITerminalSymbols ÀÎÅÍÆäÀ̽º¿¡ Á¤ÀÇµÈ Æ¯Á¤ °ªÀ» °®½À´Ï´Ù. À̰ÍÀº ¿Ã¹Ù¸¥ ÅäÅ«ÀÇ ¹Ýº¹ ¹× °Ë»öÀ» À§ÇØ ¸Å¿ì °£´ÜÇÕ´Ï´Ù. SuperMethodInvocation¿¡¼­ super Ű¿öµåÀÇ À§Ä¡¸¦ ãÀ¸·Á¸é ½ºÄ³³Ê¸¦ »ç¿ëÇϽʽÿÀ.

¼Ò½º ÄÚµå ¼öÁ¤

ÀϺΠ¼Ò½º ÄÚµå ¼öÁ¤Àº Java ¿ä¼Ò API¸¦ ÅëÇØ Á¦°øµÇÁö ¾Ê½À´Ï´Ù. ¼Ò½º Äڵ带 ÆíÁý(±âÁ¸ ¿ä¼ÒÀÇ ¼Ò½º Äڵ带 º¯°æÇÏ´Â °Í°ú °°Àº)Çϱâ À§ÇÑ º¸´Ù ÀϹÝÀûÀÎ ¹æ¹ýÀº ÄÄÆÄÀÏ ´ÜÀ§ÀÇ ¿ø½Ã ¼Ò½º ÄÚµå ¹× DOM/ASTÀÇ API ´Ù½Ã ¾²±â¸¦ »ç¿ëÇÏ¿© ¼öÇàµË´Ï´Ù.

DOM/AST ´Ù½Ã ¾²±â¸¦ ¼öÇàÇϱâ À§ÇØ µÎ °¡Áö API ¼¼Æ®°¡ Á¦°øµÇ´Âµ¥, ÀÌ´Â ¼³¸í ´Ù½Ã ¾²±â¿Í ¼öÁ¤ ´Ù½Ã ¾²±âÀÔ´Ï´Ù.

¼³¸í API´Â AST¸¦ ¼öÁ¤ÇÏÁö ¾ÊÁö¸¸ ASTRewrite API¸¦ »ç¿ëÇÏ¿© ¼öÁ¤»çÇ×ÀÇ ¼³¸íÀ» »ý¼ºÇÕ´Ï´Ù. AST ÀçÀÛ¼ºÀÚ´Â ³ëµå¿¡ ´ëÇÑ ¼öÁ¤»çÇ× ¼³¸íÀ» ¼öÁýÇÏ¿© ÀÌµé ¼³¸íÀ» ¿ø·¡ ¼Ò½º¿¡ Àû¿ëµÉ ¼ö ÀÖ´Â ÅØ½ºÆ® ÆíÁýÀ¸·Î º¯È¯ÇÕ´Ï´Ù.

   // creation of a Document
   ICompilationUnit cu = ... ; // content is "public class X {\n}"
   String source = cu.getBuffer().getContents();
   Document document= new Document(source);

   // creation of DOM/AST from a ICompilationUnit
   ASTParser parser = ASTParser.newParser(AST.JLS2);
   parser.setSource(cu);
   CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);

   // creation of ASTRewrite
   ASTRewrite rewrite = new ASTRewrite(astRoot.getAST());

   // description of the change
   SimpleName oldName = ((TypeDeclaration)astRoot.types().get(0)).getName();
   SimpleName newName = astRoot.getAST().newSimpleName("Y");
   rewrite.replace(oldName, newName, null);

   // computation of the text edits
   TextEdit edits = rewrite.rewriteAST(document, cu.getJavaProject().getOptions(true));

   // computation of the new source code
   edits.apply(document);
   String newSource = document.get();

   // update of the compilation unit
   cu.getBuffer().setContents(newSource);

API¸¦ ¼öÁ¤Çϸé AST¸¦ Á÷Á¢ ¼öÁ¤ÇÒ ¼ö ÀÖ½À´Ï´Ù.

   // creation of a Document
   ICompilationUnit cu = ... ; // content is "public class X {\n}"
   String source = cu.getBuffer().getContents();
   Document document= new Document(source);

   // creation of DOM/AST from a ICompilationUnit
   ASTParser parser = ASTParser.newParser(AST.JLS2);
   parser.setSource(cu);
   CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);

   // start record of the modifications
   astRoot.recordModifications();

   // modify the AST
   TypeDeclaration typeDeclaration = (TypeDeclaration)astRoot.types().get(0)
   SimpleName newName = astRoot.getAST().newSimpleName("Y");
   typeDeclaration.setName(newName);

   // computation of the text edits
   TextEdit edits = astRoot.rewrite(document, cu.getJavaProject().getOptions(true));

   // computation of the new source code
   edits.apply(document);
   String newSource = document.get();

   // update of the compilation unit
   cu.getBuffer().setContents(newSource);

Java ¿ä¼ÒÀÇ º¯°æ»çÇ׿¡ ´ëÇÑ ÀÀ´ä

Ç÷¯±×ÀÎÀÌ »çÈÄ¿¡ Java ¿ä¼Ò¿¡ ´ëÇÑ º¯°æ»çÇ×À» ¾Ë¾Æ¾ß ÇÒ °æ¿ì Java IElementChangedListener¸¦ JavaCore¿¡ µî·ÏÇÒ ¼ö ÀÖ½À´Ï´Ù.

   JavaCore.addElementChangedListener(new MyJavaElementChangeReporter());

addElementChangedListener(IElementChangedListener, int)¸¦ »ç¿ë Áß¿¡ °ü½ÉÀÖ´Â À̺¥Æ®ÀÇ À¯ÇüÀ» ÁöÁ¤ÇÏ¿© Á» ´õ ±¸Ã¼ÀûÀÏ ¼ö ÀÖ½À´Ï´Ù.

¿¹¸¦ µé¾î, Á¶Á¤ Á¶ÀÛ Áß À̺¥Æ® ûÃë¿¡¸¸ °ü½ÉÀÌ ÀÖ´Â °æ¿ì,

   JavaCore.addElementChangedListener(new MyJavaElementChangeReporter(), ElementChangedEvent.POST_RECONCILE);

JavaCore°¡ Áö¿øÇÏ´Â À̺¥Æ® Á¾·ù¿¡´Â µÎ °¡Áö°¡ ÀÖ½À´Ï´Ù.

Java ¿ä¼Ò º¯°æ ¸®½º³Ê´Â ÀÚ¿ø º¯°æ ¸®½º³Ê(ÀÚ¿ø º¯°æ ÃßÀû¿¡ ¼³¸í)¿Í °³³äÀûÀ¸·Î À¯»çÇÕ´Ï´Ù. ´ÙÀ½ ½º´ÏÆêÀº ½Ã½ºÅÛ ÄܼÖÀÇ ¿ä¼Ò µ¨Å¸¸¦ ÀμâÇÏ´Â Java ¿ä¼Ò º¯°æ º¸°í¼­¸¦ ±¸ÇöÇÕ´Ï´Ù.

   public class MyJavaElementChangeReporter implements IElementChangedListener {
      public void elementChanged(ElementChangedEvent event) {
         IJavaElementDelta delta= event.getDelta();
         if (delta != null) {
            System.out.println("delta received: ");
            System.out.print(delta);
         }
      }
   }

IJavaElementDelta¿¡´Â º¯°æµÈ ¿ä¼Ò¿Í º¯°æ À¯ÇüÀ» ¼³¸íÇÏ´Â Ç÷¡±×°¡ ÀÖ½À´Ï´Ù. ´ëºÎºÐÀÇ µ¨Å¸ Æ®¸®´Â Java ¸ðµ¨ ·¹º§À» ±Ù°Å·Î ÇÕ´Ï´Ù. Ŭ¶óÀÌ¾ðÆ®´Â ¾î¶² ÇÁ·ÎÁ§Æ®°¡ º¯°æµÇ¾ú´ÂÁö ¾Ë¾Æº¸±â À§ÇØ getAffectedChildrenÀ» »ç¿ëÇÏ¿© ÀÌ µ¨Å¸¸¦ Ž»öÇØ¾ß ÇÕ´Ï´Ù.

´ÙÀ½ ¿¹Á¦ ¸Þ¼Òµå´Â µ¨Å¸¸¦ Åë°úÇϰí Ãß°¡, Á¦°Å ¹× ¼öÁ¤µÈ ¿ä¼Ò¸¦ ÀμâÇÕ´Ï´Ù.

    void traverseAndPrint(IJavaElementDelta delta) {
        switch (delta.getKind()) {
            case IJavaElementDelta.ADDED:
                System.out.println(delta.getElement() + " was added");
                break;
            case IJavaElementDelta.REMOVED:
                System.out.println(delta.getElement() + " was removed");
                break;
            case IJavaElementDelta.CHANGED:
                System.out.println(delta.getElement() + " was changed");
                if ((delta.getFlags() & IJavaElementDelta.F_CHILDREN) != 0) {
                    System.out.println("The change was in its children");
                }
                if ((delta.getFlags() & IJavaElementDelta.F_CONTENT) != 0) {
                    System.out.println("The change was in its content");
                }
                /* Others flags can also be checked */
                break;
        }
        IJavaElementDelta[] children = delta.getAffectedChildren();
        for (int i = 0; i < children.length; i++) {
            traverseAndPrint(children[i]);
        }
    }

Á¶ÀÛÀÇ ¸î¸î Á¾·ù´Â Java ¿ä¼Ò º¯°æ °ø°í¸¦ Æ®¸®°ÅÇÒ ¼ö ÀÖ½À´Ï´Ù. ´ÙÀ½Àº ÀϺΠ¿¹ÀÔ´Ï´Ù.

IResourceDelta¿¡ ´ëÇØ Java ¿ä¼Ò µ¨Å¸´Â IWorkspaceRunnable¸¦ »ç¿ëÇÏ¿© Àϰýó¸®µÉ ¼ö ÀÖ½À´Ï´Ù. IWorkspaceRunnable ³»¿¡¼­ ½ÇÇàµÇ´Â ÀϺΠJava ¸ðµ¨·ÎºÎÅÍÀÇ µ¨Å¸ °á°ú´Â º´ÇյǾî Çѹø¿¡ º¸°íµË´Ï´Ù.  

JavaCore ´Â Java ¿ä¼Ò º¯°æ»çÇ×À» Àϰýó¸® Çϱâ À§ÇÑ ½ÇÇà ¸Þ¼Òµå¸¦ Á¦°øÇÕ´Ï´Ù.

¿¹¸¦ µé¾î, ´ÙÀ½ ÄÚµå ´ÜÆíÀº 2°³ÀÇ Java ¿ä¼Ò º¯°æ À̺¥Æ®¸¦ Æ®¸®°ÅÇÕ´Ï´Ù.

    // Get package
    IPackageFragment pkg = ...;
    
    // Create 2 compilation units
 	            ICompilationUnit unitA = pkg.createCompilationUnit("A.java", "public class A {}", false, null);
 	            ICompilationUnit unitB = pkg.createCompilationUnit("B.java", "public class B {}", false, null);

¹Ý¸é¿¡ ´ÙÀ½ ÄÚµå ´ÜÆíÀº 1°³ÀÇ Java ¿ä¼Ò º¯°æ À̺¥Æ®¸¦ Æ®¸®°ÅÇÕ´Ï´Ù.

    // Get package
    IPackageFragment pkg = ...;
    
    // Create 2 compilation units
    JavaCore.run(
        new IWorkspaceRunnable() {
 	        public void run(IProgressMonitor monitor) throws CoreException {
 	            ICompilationUnit unitA = pkg.createCompilationUnit("A.java", "public class A {}", false, null);
 	            ICompilationUnit unitB = pkg.createCompilationUnit("B.java", "public class B {}", false, null);
 	        }
        },
        null);

¹ýÀû ÁÖÀÇ»çÇ×