Home » Language IDEs » Java Development Tools (JDT) » Programaticaly change an annotaion
Programaticaly change an annotaion [message #250475] |
Mon, 07 January 2008 03:34  |
Eclipse User |
|
|
|
Hi all,
Thanks for helping me.
Using eclipse 3.4M4 I am trying to programaticaly change the value of an
annotation.
I would like to do it in such a way that
IJavaElementDelta.getAnnotationsDelta() will return the right result.
So I thought that using ASTRewrite with the appropriate IDocument and
ITextFileBuffer will very much simulate the way a user edits a java file. I
am using the following code.
The code is executed in a unit test.
public static void changeAnnotation(IType type, String annotation,
Map<String, String> valuePairs,
IProgressMonitor monitor) throws Exception {
ICompilationUnit unit = (ICompilationUnit) type.getCompilationUnit();
ITextFileBufferManager bufferManager =
FileBuffers.getTextFileBufferManager();
IPath path = unit.getPath();
try {
bufferManager.connect(path, LocationKind.IFILE, monitor); // (1)
ITextFileBuffer textFileBuffer =
bufferManager.getTextFileBuffer(path, LocationKind.IFILE);
IDocument document = textFileBuffer.getDocument();
ASTRewrite rewrite = basicChangeAnnotation(type, annotation,
valuePairs);
TextEdit textEdit = rewrite.rewriteAST(document,
Collections.emptyMap());
textEdit.apply(document);
textFileBuffer.commit(monitor, false);
} finally {
bufferManager.disconnect(path, LocationKind.IFILE, monitor);
}
Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, monitor);
}
The method basicChangeAnnotation() is actually creating the new annotation
with the new member value pairs and is replacing the old annotation.
The full code can be foud in the attached file.
The problem is that when I get an ElementChangedEvent the method
event.getDelta().getResourceDeltas() returns "null" and
event.getDelta.getAnnotationDeltas() returns an empty array?
I have checked https://bugs.eclipse.org/bugs/show_bug.cgi?id=210310 and
https://bugs.eclipse.org/bugs/show_bug.cgi?id=79112. And I am using M4.
Best Regards,
Kiril
Attachment: JDTUtil.java
(Size: 4.91KB, Downloaded 315 times)
|
|
|
Re: Programaticaly change an annotaion [message #250482 is a reply to message #250475] |
Mon, 07 January 2008 03:55   |
Eclipse User |
|
|
|
The JDTUtil file that I have attached is not viewed in the web page of the
newsgroup.
"This can only happen using Micro$oft products :("
So I will just past its code.
package org.eclipse.sapEjb;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;
public final class JDTUtil {
public static void changeAnnotation(IType type, String annotation,
Map<String, String> valuePairs,
IProgressMonitor monitor) throws Exception {
ICompilationUnit unit = (ICompilationUnit) type.getCompilationUnit();
ITextFileBufferManager bufferManager =
FileBuffers.getTextFileBufferManager();
IPath path = unit.getPath();
try {
bufferManager.connect(path, LocationKind.IFILE, monitor); // (1)
ITextFileBuffer textFileBuffer = bufferManager.getTextFileBuffer(path,
LocationKind.IFILE);
IDocument document = textFileBuffer.getDocument();
// ... edit the document here ...
ASTRewrite rewrite = basicChangeAnnotation(type, annotation, valuePairs);
TextEdit textEdit = rewrite.rewriteAST(document, Collections.emptyMap());
textEdit.apply(document);
textFileBuffer.commit(monitor, false);
} finally {
bufferManager.disconnect(path, LocationKind.IFILE, monitor);
}
Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, monitor);
}
public static IType[] getTypes(IFile file) throws JavaModelException {
return ((ICompilationUnit) JavaCore.create(file)).getTypes();
}
private static ASTRewrite basicChangeAnnotation(IType type, String
annotation, Map<String, String> valuePairs) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(type.getCompilationUnit());
parser.setResolveBindings(false);
CompilationUnit astUnit = (CompilationUnit) parser.createAST(null);
TypeDeclaration typeDeclaration = null;
for (Iterator iter = astUnit.types().iterator(); iter.hasNext();) {
TypeDeclaration declaration = (TypeDeclaration) iter.next();
if (declaration.getName().getIdentifier().equals(type.getElemen tName()))
{
typeDeclaration = declaration;
break;
}
}
Annotation oldAnnotation = getAnnotation(typeDeclaration, annotation);
AST newAST = oldAnnotation.getAST();
NormalAnnotation newAnnotation = createAnnotation(oldAnnotation.getAST(),
valuePairs);
ASTRewrite rewrite = ASTRewrite.create(oldAnnotation.getAST());
rewrite.replace(oldAnnotation, newAnnotation, null);
return rewrite;
}
private static Annotation getAnnotation(TypeDeclaration typeDeclaration,
String annotation) {
for (Iterator iter = typeDeclaration.modifiers().iterator();
iter.hasNext();) {
IExtendedModifier element = (IExtendedModifier) iter.next();
if (element.isAnnotation()) {
if (((Annotation)
element).getTypeName().getFullyQualifiedName().equals(annota tion))
return (Annotation) element;
}
}
return (Annotation) new Object();
}
private static NormalAnnotation createAnnotation(AST ast, Map<String,
String> valuePairs) {
NormalAnnotation newAnnotation = ast.newNormalAnnotation();
newAnnotation.setTypeName(newAnnotation.getAST().newName("SomeAnnotation "));
for (Map.Entry<String, String> entry : valuePairs.entrySet()) {
MemberValuePair valuePair = createValuePair(newAnnotation.getAST(),
entry.getKey(), entry.getValue());
newAnnotation.values().add(valuePair);
}
return newAnnotation;
}
private static MemberValuePair createValuePair(AST ast, String key, String
value) {
MemberValuePair pair = ast.newMemberValuePair();
pair.setName(pair.getAST().newSimpleName(key));
StringLiteral literal = pair.getAST().newStringLiteral();
literal.setLiteralValue(value);
pair.setValue(literal);
return pair;
}
}
Best Regards,
Kiril
|
|
| |
Re: Programaticaly change an annotaion [message #250658 is a reply to message #250532] |
Mon, 14 January 2008 02:52  |
Eclipse User |
|
|
|
Thanks Jerome,
I now get it.My compilation unit is a working copy. And I never call
commitWorkingCopy().
textFileBuffer.commit(monitor, false) is committing the change on the
disk, but it is using IFile.setContents().
I will try with commitWorkingCopy().
Jerome Lanneluc wrote:
> Is your compilation unit a working copy?
> You will get annotation deltas only when the working copy is reconciled
> (see ICompilationUnit#reconcile(...))
> or when it is commited to disk (see
> ICompilationUnit#commitWorkingCopy(...)).
>
> Jerome
|
|
|
Goto Forum:
Current Time: Tue May 06 05:41:20 EDT 2025
Powered by FUDForum. Page generated in 0.27249 seconds
|