Skip to main content



      Home
Home » Language IDEs » Java Development Tools (JDT) » Programaticaly change an annotaion
Programaticaly change an annotaion [message #250475] Mon, 07 January 2008 03:34 Go to next message
Eclipse UserFriend
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 Go to previous messageGo to next message
Eclipse UserFriend
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 #250532 is a reply to message #250475] Wed, 09 January 2008 12:39 Go to previous messageGo to next message
Eclipse UserFriend
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
Re: Programaticaly change an annotaion [message #250658 is a reply to message #250532] Mon, 14 January 2008 02:52 Go to previous message
Eclipse UserFriend
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
Previous Topic:Increase visibility of a method via content assist
Next Topic:Package explorer: (default package) always shown, why?
Goto Forum:
  


Current Time: Tue May 06 05:41:20 EDT 2025

Powered by FUDForum. Page generated in 0.27249 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top