blob: dfa9e51852391f5ee50ad22e0c2e1276bc27d783 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2008 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0, which accompanies this distribution
* and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.core.internal.utility.jdt;
import java.util.List;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.core.utility.jdt.AnnotationEditFormatter;
import org.eclipse.jpt.core.utility.jdt.FieldAttribute;
import org.eclipse.jpt.core.utility.jdt.Type;
import org.eclipse.jpt.utility.CommandExecutorProvider;
/**
* Adapt and extend a JDT field.
* Attribute based on a Java field, e.g.
* private int foo;
*/
public class JDTFieldAttribute
extends JDTAttribute
implements FieldAttribute
{
// ********** constructors **********
public JDTFieldAttribute(
Type declaringType,
String name,
int occurrence,
ICompilationUnit compilationUnit,
CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
this(declaringType, name, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, DefaultAnnotationEditFormatter.instance());
}
public JDTFieldAttribute(
Type declaringType,
String name,
int occurrence,
ICompilationUnit compilationUnit,
CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
AnnotationEditFormatter annotationEditFormatter) {
super(declaringType, name, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
}
/**
* constructor for testing
*/
public JDTFieldAttribute(Type declaringType, String name, int occurrence, ICompilationUnit compilationUnit) {
this(declaringType, name, occurrence, compilationUnit, CommandExecutorProvider.Default.instance(), DefaultAnnotationEditFormatter.instance());
}
// ********** Member/Attribute/FieldAttribute implementation **********
public IVariableBinding getBinding(CompilationUnit astRoot) {
return this.getFragment(astRoot).resolveBinding();
}
public FieldDeclaration getBodyDeclaration(CompilationUnit astRoot) {
return this.getSelectedDeclaration(astRoot, FIELD_DECLARATION_SELECTOR);
}
public TextRange getNameTextRange(CompilationUnit astRoot) {
return new ASTNodeTextRange(this.getFragment(astRoot).getName());
}
public String getAttributeName() {
return this.getName_();
}
public ITypeBinding getTypeBinding(CompilationUnit astRoot) {
return this.getBodyDeclaration(astRoot).getType().resolveBinding();
}
@Override
public boolean isField() {
return true;
}
public boolean isPersistable(CompilationUnit astRoot) {
IVariableBinding binding = this.getBinding(astRoot);
return (binding == null) ? false : JPTTools.fieldIsPersistable(binding);
}
// ********** internal **********
protected VariableDeclarationFragment getFragment(CompilationUnit astRoot) {
return this.getSelectedDeclaration(astRoot, VARIABLE_DECLARATION_FRAGMENT_SELECTOR);
}
/**
* return either a FieldDeclaration or a VariableDeclarationFragment,
* depending on the specified selector;
*
* handle multiple fields declared in a single statement:
* private int foo, bar;
*/
protected <T extends ASTNode> T getSelectedDeclaration(CompilationUnit astRoot, Selector<T> selector) {
String name = this.getName_();
int occurrence = this.getOccurrence();
int count = 0;
for (FieldDeclaration fieldDeclaration : this.getDeclaringTypeFieldDeclarations(astRoot)) {
for (VariableDeclarationFragment fragment : fragments(fieldDeclaration)) {
if (fragment.getName().getFullyQualifiedName().equals(name)) {
count++;
if (count == occurrence) {
return selector.select(fieldDeclaration, fragment);
}
}
}
}
// return null if the field is no longer in the source code;
// this can happen when the context model has not yet
// been synchronized with the resource model but is still
// asking for an ASTNode (e.g. during a selection event)
return null;
}
protected FieldDeclaration[] getDeclaringTypeFieldDeclarations(CompilationUnit astRoot) {
return this.getDeclaringTypeDeclaration(astRoot).getFields();
}
// minimize scope of suppressed warnings
@SuppressWarnings("unchecked")
protected static List<VariableDeclarationFragment> fragments(FieldDeclaration fd) {
return fd.fragments();
}
// ********** Selector **********
// I'm not quite sure this interface is worth the resulting obfuscation,
// but, then, I kept changing both methods, so... ~bjv
protected interface Selector<T extends ASTNode> {
T select(FieldDeclaration fieldDeclaration, VariableDeclarationFragment variableDeclarationFragment);
String getDescription();
}
protected static final Selector<FieldDeclaration> FIELD_DECLARATION_SELECTOR =
new Selector<FieldDeclaration>() {
public FieldDeclaration select(FieldDeclaration fieldDeclaration, VariableDeclarationFragment variableDeclarationFragment) {
return fieldDeclaration;
}
public String getDescription() {
return "field declaration"; //$NON-NLS-1$
}
@Override
public String toString() {
return "FIELD_DECLARATION_SELECTOR"; //$NON-NLS-1$
}
};
protected static final Selector<VariableDeclarationFragment> VARIABLE_DECLARATION_FRAGMENT_SELECTOR =
new Selector<VariableDeclarationFragment>() {
public VariableDeclarationFragment select(FieldDeclaration fieldDeclaration, VariableDeclarationFragment variableDeclarationFragment) {
return variableDeclarationFragment;
}
public String getDescription() {
return "variable declaration fragment"; //$NON-NLS-1$
}
@Override
public String toString() {
return "VARIABLE_DECLARATION_FRAGMENT_SELECTOR"; //$NON-NLS-1$
}
};
}