Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » Java Development Tools (JDT) » Programaticaly change an annotaion
Programaticaly change an annotaion [message #250475] Mon, 07 January 2008 08:34 Go to next message
kiril mitov is currently offline kiril mitovFriend
Messages: 69
Registered: July 2009
Member
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 302 times)
Re: Programaticaly change an annotaion [message #250482 is a reply to message #250475] Mon, 07 January 2008 08:55 Go to previous messageGo to next message
kiril mitov is currently offline kiril mitovFriend
Messages: 69
Registered: July 2009
Member
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 17:39 Go to previous messageGo to next message
Jerome Lanneluc is currently offline Jerome LannelucFriend
Messages: 572
Registered: July 2009
Senior Member
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 07:52 Go to previous message
kiril mitov is currently offline kiril mitovFriend
Messages: 69
Registered: July 2009
Member
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: Sat Nov 02 20:04:31 GMT 2024

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

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

Back to the top