Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbvosburgh2008-05-15 05:29:48 +0000
committerbvosburgh2008-05-15 05:29:48 +0000
commitf0f9657d3b820c12d9658ab360947c939e6c75d9 (patch)
tree6ad923f9582ab8dec642dd1a00a74065e6dcb52f
parent2315456dc5dbd5e45bc382488eac041d0afb6d8d (diff)
downloadwebtools.dali-f0f9657d3b820c12d9658ab360947c939e6c75d9.tar.gz
webtools.dali-f0f9657d3b820c12d9658ab360947c939e6c75d9.tar.xz
webtools.dali-f0f9657d3b820c12d9658ab360947c939e6c75d9.zip
[225885] fix editing annotations with property access
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaFile.java30
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaProject.java6
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/ResourceModel.java5
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractResourceModel.java9
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaFile.java5
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java29
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java19
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentAttribute.java59
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentType.java119
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceUnit.java31
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourceNode.java39
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourcePersistentMember.java152
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourceModelImpl.java26
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentAttributeImpl.java106
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentTypeImpl.java723
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JpaCompilationUnitImpl.java215
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/synch/SynchronizeClassesJob.java13
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/ASTNodeSearchUtil.java108
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/ASTNodes.java726
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTAttribute.java46
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTFieldAttribute.java164
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMember.java143
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMethodAttribute.java156
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTModifiedDeclaration.java5
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTTools.java82
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTType.java204
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JPTTools.java4
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/NodeFinder.java111
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResource.java2
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResourceModel.java11
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceModel.java2
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceNode.java22
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentMember.java34
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentType.java20
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JpaCompilationUnit.java8
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/orm/OrmResource.java7
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/persistence/PersistenceResource.java7
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Attribute.java14
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/FieldAttribute.java10
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Member.java44
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/MethodAttribute.java17
-rw-r--r--jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Type.java37
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelection.java13
-rw-r--r--jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java81
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/CommandExecutorProvider.java23
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/MethodSignature.java63
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleJavaType.java5
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleMethodSignature.java235
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/resource/ClassTools.java1680
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java1
-rw-r--r--jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/MethodSignatureTests.java237
51 files changed, 3894 insertions, 2014 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaFile.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaFile.java
index 56c5191022..73868f9448 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaFile.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaFile.java
@@ -40,6 +40,23 @@ public interface JpaFile extends JpaNode
*/
ResourceModel getResourceModel();
+ /**
+ * Forward the Java element changed event to the JPA file's content.
+ */
+ void javaElementChanged(ElementChangedEvent event);
+
+ /**
+ * Update the JPA resource model from the underlying resource.
+ */
+ void updateFromResource();
+
+ /**
+ * The JPA file has been removed from the JPA project. Clean up any
+ * hooks to external resources etc.
+ */
+ void dispose();
+
+
// **************** root structure nodes *************************************
/**
@@ -53,6 +70,7 @@ public interface JpaFile extends JpaNode
Iterator<JpaStructureNode> rootStructureNodes();
int rootStructureNodesSize();
+
/**
* Set the root context model object represented by this JPA file.
* There is the potential for multiple root structure nodes
@@ -65,20 +83,10 @@ public interface JpaFile extends JpaNode
void addRootStructureNode(Object key, JpaStructureNode rootStructureNode);
void removeRootStructureNode(Object key);
+
/**
* Return the structure node best represented by the location in the file.
*/
JpaStructureNode getStructureNode(int textOffset);
- /**
- * Forward the Java element changed event to the JPA file's content.
- */
- void javaElementChanged(ElementChangedEvent event);
-
- /**
- * The JPA file has been removed from the JPA project. Clean up any
- * hooks to external resources etc.
- */
- void dispose();
-
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaProject.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaProject.java
index dd5f4753ff..2b4abb5adb 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaProject.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/JpaProject.java
@@ -19,7 +19,6 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IType;
import org.eclipse.jpt.core.context.JpaRootContextNode;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
import org.eclipse.jpt.db.ConnectionProfile;
@@ -185,14 +184,15 @@ public interface JpaProject extends JpaNode {
JpaRootContextNode getRootContext();
/**
- * Return an iterator on all ITypes that are annotated within this project
+ * Return the names of the JPA project's annotated classes.
*/
- Iterator<IType> annotatedClasses();
+ Iterator<String> annotatedClassNames();
/**
* Return the Java persistent type resource for the specified fully qualified type name;
* null, if none exists.
*/
+ // TODO rename getJavaResourcePersistentType(String)
JavaResourcePersistentType getJavaPersistentTypeResource(String typeName);
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/ResourceModel.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/ResourceModel.java
index f5a77731f9..c2c1f6908a 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/ResourceModel.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/ResourceModel.java
@@ -55,6 +55,11 @@ public interface ResourceModel extends Model
void javaElementChanged(ElementChangedEvent event);
+ /**
+ * Update the resource model from the underlying resource.
+ */
+ void updateFromResource();
+
void addResourceModelChangeListener(ResourceModelListener listener);
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractResourceModel.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractResourceModel.java
index 072eb7fcf3..4b67456ff2 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractResourceModel.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/AbstractResourceModel.java
@@ -17,10 +17,10 @@ public abstract class AbstractResourceModel
extends AbstractModel
implements ResourceModel
{
-
protected final IFile file;
-
+
protected AbstractResourceModel(IFile file) {
+ super();
this.file = file;
}
@@ -28,9 +28,8 @@ public abstract class AbstractResourceModel
return this.file;
}
- public abstract Object getResource();
-
-
public void dispose() {
+ // do nothing by default
}
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaFile.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaFile.java
index 1f15eb65a3..c180d7c15b 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaFile.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaFile.java
@@ -123,4 +123,9 @@ public class GenericJpaFile extends AbstractJpaNode implements JpaFile
sb.append(getResourceType());
sb.append(")");
}
+
+ public void updateFromResource() {
+ this.resourceModel.updateFromResource();
+ }
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java
index 566ac28a1c..da6eb5bc3e 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/GenericJpaProject.java
@@ -13,6 +13,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
+
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
@@ -23,14 +24,11 @@ import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jpt.core.JpaDataSource;
import org.eclipse.jpt.core.JpaFile;
import org.eclipse.jpt.core.JpaPlatform;
@@ -392,31 +390,20 @@ public class GenericJpaProject extends AbstractJpaNode implements JpaProject {
// ********** more queries **********
- public Iterator<IType> annotatedClasses() {
- return new FilteringIterator<IType, IType>(
- new TransformationIterator<JavaResourcePersistentType, IType>(annotatedJavaPersistentTypes()) {
- @Override
- protected IType transform(JavaResourcePersistentType next) {
- try {
- return getJavaProject().findType(next.getQualifiedName(), new NullProgressMonitor());
- }
- catch (JavaModelException jme) {
- return null;
- }
- }
- }) {
+ public Iterator<String> annotatedClassNames() {
+ return new TransformationIterator<JavaResourcePersistentType, String>(this.annotatedJavaPersistentTypes()) {
@Override
- protected boolean accept(IType o) {
- return o != null;
+ protected String transform(JavaResourcePersistentType next) {
+ return next.getQualifiedName();
}
};
}
protected Iterator<JavaResourcePersistentType> annotatedJavaPersistentTypes() {
- return new FilteringIterator<JavaResourcePersistentType, JavaResourcePersistentType>(javaResourcePersistentTypes()) {
+ return new FilteringIterator<JavaResourcePersistentType, JavaResourcePersistentType>(this.javaResourcePersistentTypes()) {
@Override
protected boolean accept(JavaResourcePersistentType persistentType) {
- return persistentType == null ? false : persistentType.isPersisted();
+ return (persistentType == null) ? false : persistentType.isPersisted();
}
};
}
@@ -442,7 +429,7 @@ public class GenericJpaProject extends AbstractJpaNode implements JpaProject {
return new TransformationIterator<JpaFile, JpaCompilationUnit>(this.javaJpaFiles()) {
@Override
protected JpaCompilationUnit transform(JpaFile jpaFile) {
- return ((JavaResourceModel) jpaFile.getResourceModel()).getResource();
+ return ((JavaResourceModel) jpaFile.getResourceModel()).getJpaCompilationUnit();
}
};
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java
index 3df53ba009..9151a05981 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/GenericRootContextNode.java
@@ -14,7 +14,6 @@ import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jdt.core.IType;
import org.eclipse.jpt.core.JpaProject;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.context.JpaContextNode;
@@ -224,37 +223,37 @@ public class GenericRootContextNode extends AbstractJpaContextNode
if (getJpaProject().discoversAnnotatedClasses()) {
return;
}
- Collection<IType> orphanedClasses = CollectionTools.collection(getJpaProject().annotatedClasses());
+ Collection<String> orphanedClassNames = CollectionTools.collection(getJpaProject().annotatedClassNames());
if (getPersistenceXml().getPersistence().persistenceUnitsSize() != 1) {
//context model currently only supports 1 persistenceUnit
return;
}
PersistenceUnit persistenceUnit = getPersistenceXml().getPersistence().persistenceUnits().next();
- for (IType type : CollectionTools.iterable(getJpaProject().annotatedClasses())) {
+ for (String typeName : CollectionTools.iterable(getJpaProject().annotatedClassNames())) {
for (ClassRef classRef : CollectionTools.iterable(persistenceUnit.specifiedClassRefs())) {
- if (classRef.isFor(type.getFullyQualifiedName('.'))) {
- orphanedClasses.remove(type);
+ if (classRef.isFor(typeName)) {
+ orphanedClassNames.remove(typeName);
}
}
for (MappingFileRef mappingFileRef : CollectionTools.iterable(persistenceUnit.mappingFileRefs())) {
if (mappingFileRef.getOrmXml() == null || mappingFileRef.getOrmXml().getEntityMappings() == null) {
continue;
}
- if (mappingFileRef.getOrmXml().getEntityMappings().getPersistentType(type.getFullyQualifiedName('.')) != null) {
- orphanedClasses.remove(type);
+ if (mappingFileRef.getOrmXml().getEntityMappings().getPersistentType(typeName) != null) {
+ orphanedClassNames.remove(typeName);
}
}
}
- for (IType orphanedType : orphanedClasses) {
- JavaResourcePersistentType javaResourcePersistentType = getJpaProject().getJavaPersistentTypeResource(orphanedType.getFullyQualifiedName('.'));
+ for (String orphanedTypeName : orphanedClassNames) {
+ JavaResourcePersistentType javaResourcePersistentType = getJpaProject().getJavaPersistentTypeResource(orphanedTypeName);
messages.add(
DefaultJpaValidationMessages.buildMessage(
IMessage.HIGH_SEVERITY,
JpaValidationMessages.PERSISTENT_TYPE_UNSPECIFIED_CONTEXT,
new String[] {persistenceUnit.getName()},
javaResourcePersistentType.getResourceModel().getFile(),
- javaResourcePersistentType.getMappingAnnotation().getTextRange(JDTTools.buildASTRoot(orphanedType)))
+ javaResourcePersistentType.getMappingAnnotation().getTextRange(JDTTools.buildASTRoot(javaResourcePersistentType.getJpaCompilationUnit().getCompilationUnit())))
);
}
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentAttribute.java
index 36cb7608d3..7c0cfcd257 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentAttribute.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentAttribute.java
@@ -21,6 +21,7 @@ import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.core.context.java.JavaPersistentType;
import org.eclipse.jpt.core.context.java.JavaStructureNodes;
import org.eclipse.jpt.core.context.java.JavaTypeMapping;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
import org.eclipse.jpt.core.resource.java.Annotation;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.core.utility.TextRange;
@@ -193,16 +194,11 @@ public class GenericJavaPersistentAttribute extends AbstractJavaJpaContextNode
public boolean contains(int offset, CompilationUnit astRoot) {
TextRange fullTextRange = this.getFullTextRange(astRoot);
- if (fullTextRange == null) {
- //This happens if the attribute no longer exists in the java.
- //The text selection event is fired before the update from java so our
- //model has not yet had a chance to update appropriately. The list of
- //JavaPersistentAttriubtes is stale at this point. For now, we are trying
- //to avoid the NPE, not sure of the ultimate solution to these 2 threads accessing
- //our model
- return false;
- }
- return fullTextRange.includes(offset);
+ // 'fullTextRange' will be null if the attribute no longer exists in the java;
+ // the context model can be out of synch with the resource model
+ // when a selection event occurs before the context model has a
+ // chance to synch with the resource model via the update thread
+ return (fullTextRange == null) ? false : fullTextRange.includes(offset);
}
@@ -219,52 +215,55 @@ public class GenericJavaPersistentAttribute extends AbstractJavaJpaContextNode
}
public TextRange getSelectionTextRange() {
- return getSelectionTextRange(this.resourcePersistentAttribute.getMember().getAstRoot());
+ return getSelectionTextRange(this.buildASTRoot());
+ }
+
+ protected CompilationUnit buildASTRoot() {
+ return JDTTools.buildASTRoot(this.resourcePersistentAttribute.getJpaCompilationUnit().getCompilationUnit());
}
-
- public void update(JavaResourcePersistentAttribute resourcePersistentAttribute) {
- this.resourcePersistentAttribute = resourcePersistentAttribute;
- this.setName(this.name(resourcePersistentAttribute));
- this.updateDefaultMapping(resourcePersistentAttribute);
- this.updateSpecifiedMapping(resourcePersistentAttribute);
+ public void update(JavaResourcePersistentAttribute jrpa) {
+ this.resourcePersistentAttribute = jrpa;
+ this.setName(this.name(jrpa));
+ this.updateDefaultMapping(jrpa);
+ this.updateSpecifiedMapping(jrpa);
}
- protected String name(JavaResourcePersistentAttribute resourcePersistentAttribute) {
- return resourcePersistentAttribute.getName();
+ protected String name(JavaResourcePersistentAttribute jrpa) {
+ return jrpa.getName();
}
public String specifiedMappingAnnotationName() {
return (this.specifiedMapping == null) ? null : this.specifiedMapping.getAnnotationName();
}
- protected void updateSpecifiedMapping(JavaResourcePersistentAttribute resourcePersistentAttribute) {
- String javaMappingAnnotationName = this.javaMappingAnnotationName(resourcePersistentAttribute);
+ protected void updateSpecifiedMapping(JavaResourcePersistentAttribute jrpa) {
+ String javaMappingAnnotationName = this.javaMappingAnnotationName(jrpa);
if (specifiedMappingAnnotationName() != javaMappingAnnotationName) {
- setSpecifiedMapping(createJavaAttributeMappingFromAnnotation(javaMappingAnnotationName, resourcePersistentAttribute));
+ setSpecifiedMapping(createJavaAttributeMappingFromAnnotation(javaMappingAnnotationName, jrpa));
}
else {
if (getSpecifiedMapping() != null) {
- getSpecifiedMapping().update(resourcePersistentAttribute);
+ getSpecifiedMapping().update(jrpa);
}
}
}
- protected void updateDefaultMapping(JavaResourcePersistentAttribute resourcePersistentAttribute) {
+ protected void updateDefaultMapping(JavaResourcePersistentAttribute jrpa) {
String defaultMappingKey = getJpaPlatform().defaultJavaAttributeMappingKey(this);
if (getDefaultMapping().getKey() != defaultMappingKey) {
JavaAttributeMapping oldDefaultMapping = this.defaultMapping;
this.defaultMapping = getJpaPlatform().buildDefaultJavaAttributeMapping(this);
- this.defaultMapping.initializeFromResource(resourcePersistentAttribute);
+ this.defaultMapping.initializeFromResource(jrpa);
firePropertyChanged(PersistentAttribute.DEFAULT_MAPPING_PROPERTY, oldDefaultMapping, this.defaultMapping);
}
else {
- getDefaultMapping().update(resourcePersistentAttribute);
+ getDefaultMapping().update(jrpa);
}
}
- protected String javaMappingAnnotationName(JavaResourcePersistentAttribute resourcePersistentAttribute) {
- Annotation mappingAnnotation = (Annotation) resourcePersistentAttribute.getMappingAnnotation();
+ protected String javaMappingAnnotationName(JavaResourcePersistentAttribute jrpa) {
+ Annotation mappingAnnotation = (Annotation) jrpa.getMappingAnnotation();
if (mappingAnnotation != null) {
return mappingAnnotation.getAnnotationName();
}
@@ -278,12 +277,12 @@ public class GenericJavaPersistentAttribute extends AbstractJavaJpaContextNode
return getJpaPlatform().buildJavaAttributeMappingFromMappingKey(key, this);
}
- protected JavaAttributeMapping createJavaAttributeMappingFromAnnotation(String annotationName, JavaResourcePersistentAttribute resourcePersistentAttribute) {
+ protected JavaAttributeMapping createJavaAttributeMappingFromAnnotation(String annotationName, JavaResourcePersistentAttribute jrpa) {
if (annotationName == null) {
return null;
}
JavaAttributeMapping mapping = getJpaPlatform().buildJavaAttributeMappingFromAnnotation(annotationName, this);
- mapping.initializeFromResource(resourcePersistentAttribute);
+ mapping.initializeFromResource(jrpa);
return mapping;
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentType.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentType.java
index d929b06059..94c1b84132 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentType.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/java/GenericJavaPersistentType.java
@@ -14,6 +14,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+
import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.JpaFile;
@@ -27,6 +28,7 @@ import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.core.context.java.JavaPersistentType;
import org.eclipse.jpt.core.context.java.JavaStructureNodes;
import org.eclipse.jpt.core.context.java.JavaTypeMapping;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
import org.eclipse.jpt.core.resource.java.Annotation;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
@@ -63,7 +65,7 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
@Override
public IResource getResource() {
- return this.resourcePersistentType.getResourceModel().getResource().getCompilationUnit().getResource();
+ return this.resourcePersistentType.getResourceModel().getJpaCompilationUnit().getCompilationUnit().getResource();
}
//****************** JpaStructureNode implementation *******************
@@ -218,13 +220,14 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
return EmptyIterator.instance();
}
+ // it would be nice if the we passed in an astRoot here, but then we
+ // would need to pass it to the XML structure nodes too...
public JpaStructureNode getStructureNode(int offset) {
- //TODO astRoot, possibly get this instead of rebuilding it
- CompilationUnit astRoot = this.resourcePersistentType.getMember().getAstRoot();
+ CompilationUnit astRoot = this.buildASTRoot();
- if (contains(offset, astRoot)) {
- for (Iterator<JavaPersistentAttribute> i = attributes(); i.hasNext();) {
- JavaPersistentAttribute persistentAttribute = i.next();
+ if (this.contains(offset, astRoot)) {
+ for (Iterator<JavaPersistentAttribute> stream = this.attributes(); stream.hasNext();) {
+ JavaPersistentAttribute persistentAttribute = stream.next();
if (persistentAttribute.contains(offset, astRoot)) {
return persistentAttribute;
}
@@ -234,22 +237,21 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
return null;
}
+ protected CompilationUnit buildASTRoot() {
+ return JDTTools.buildASTRoot(this.resourcePersistentType.getJpaCompilationUnit().getCompilationUnit());
+ }
+
public boolean contains(int offset, CompilationUnit astRoot) {
TextRange fullTextRange = this.getFullTextRange(astRoot);
- if (fullTextRange == null) {
- //This happens if the attribute no longer exists in the java.
- //The text selection event is fired before the update from java so our
- //model has not yet had a chance to update appropriately. The list of
- //JavaPersistentAttriubtes is stale at this point. For now, we are trying
- //to avoid the NPE, not sure of the ultimate solution to these 2 threads accessing
- //our model
- return false;
- }
- return fullTextRange.includes(offset);
+ // 'fullTextRange' will be null if the type no longer exists in the java;
+ // the context model can be out of synch with the resource model
+ // when a selection event occurs before the context model has a
+ // chance to synch with the resource model via the update thread
+ return (fullTextRange == null) ? false : fullTextRange.includes(offset);
}
- public TextRange getFullTextRange(CompilationUnit astRoot) {
+ protected TextRange getFullTextRange(CompilationUnit astRoot) {
return this.resourcePersistentType.getTextRange(astRoot);
}
@@ -262,7 +264,7 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
}
public TextRange getSelectionTextRange() {
- return this.getSelectionTextRange(this.resourcePersistentType.getMember().getAstRoot());
+ return this.getSelectionTextRange(this.buildASTRoot());
}
@@ -288,13 +290,13 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
}
// ******************** Updating **********************
- protected void initialize(JavaResourcePersistentType resourcePersistentType) {
- this.resourcePersistentType = resourcePersistentType;
- this.parentPersistentType = this.parentPersistentType(resourcePersistentType);
- this.access = this.access(resourcePersistentType);
- this.name = this.name(resourcePersistentType);
- this.initializeMapping(resourcePersistentType);
- this.initializePersistentAttributes(resourcePersistentType);
+ protected void initialize(JavaResourcePersistentType jrpt) {
+ this.resourcePersistentType = jrpt;
+ this.parentPersistentType = this.parentPersistentType(jrpt);
+ this.access = this.access(jrpt);
+ this.name = this.name(jrpt);
+ this.initializeMapping(jrpt);
+ this.initializePersistentAttributes(jrpt);
}
protected void initializeMapping(JavaResourcePersistentType persistentTypeResource) {
@@ -313,18 +315,18 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
}
}
- public void update(JavaResourcePersistentType resourcePersistentType) {
- this.resourcePersistentType = resourcePersistentType;
+ public void update(JavaResourcePersistentType jrpt) {
+ this.resourcePersistentType = jrpt;
getJpaFile(this.resourcePersistentType.getResourceModel()).addRootStructureNode(this.resourcePersistentType.getQualifiedName(), this);
- updateParentPersistentType(resourcePersistentType);
- updateAccess(resourcePersistentType);
- updateName(resourcePersistentType);
- updateMapping(resourcePersistentType);
- updatePersistentAttributes(resourcePersistentType);
+ updateParentPersistentType(jrpt);
+ updateAccess(jrpt);
+ updateName(jrpt);
+ updateMapping(jrpt);
+ updatePersistentAttributes(jrpt);
}
- protected void updateAccess(JavaResourcePersistentType resourcePersistentType) {
- this.setAccess(this.access(resourcePersistentType));
+ protected void updateAccess(JavaResourcePersistentType jrpt) {
+ this.setAccess(this.access(jrpt));
}
/**
@@ -336,7 +338,7 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
* If still null check the persistence-unit default Access
* Default to FIELD if all else fails.
*/
- protected AccessType access(JavaResourcePersistentType resourcePersistentType) {
+ protected AccessType access(JavaResourcePersistentType jrpt) {
AccessType javaAccess = null;
boolean metadataComplete = false;
if (getOrmPersistentType() != null) {
@@ -344,7 +346,7 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
metadataComplete = getOrmPersistentType().getMapping().isMetadataComplete();
}
if (javaAccess == null && !metadataComplete) {
- javaAccess = AccessType.fromJavaResourceModel(resourcePersistentType.getAccess());
+ javaAccess = AccessType.fromJavaResourceModel(jrpt.getAccess());
}
if (javaAccess == null) {
if (getParentPersistentType() != null) {
@@ -369,21 +371,21 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
return javaAccess;
}
- protected void updateName(JavaResourcePersistentType resourcePersistentType) {
- this.setName(this.name(resourcePersistentType));
+ protected void updateName(JavaResourcePersistentType jrpt) {
+ this.setName(this.name(jrpt));
}
- protected String name(JavaResourcePersistentType resourcePersistentType) {
- return resourcePersistentType.getQualifiedName();
+ protected String name(JavaResourcePersistentType jrpt) {
+ return jrpt.getQualifiedName();
}
- protected void updateMapping(JavaResourcePersistentType resourcePersistentType) {
- String javaMappingAnnotationName = this.javaMappingAnnotationName(resourcePersistentType);
+ protected void updateMapping(JavaResourcePersistentType jrpt) {
+ String javaMappingAnnotationName = this.javaMappingAnnotationName(jrpt);
if (getMapping().getAnnotationName() != javaMappingAnnotationName) {
- setMapping(createJavaTypeMappingFromAnnotation(javaMappingAnnotationName, resourcePersistentType));
+ setMapping(createJavaTypeMappingFromAnnotation(javaMappingAnnotationName, jrpt));
}
else {
- getMapping().update(resourcePersistentType);
+ getMapping().update(jrpt);
}
}
@@ -391,25 +393,25 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
return getJpaPlatform().buildJavaTypeMappingFromMappingKey(key, this);
}
- protected JavaTypeMapping createJavaTypeMappingFromAnnotation(String annotationName, JavaResourcePersistentType resourcePersistentType) {
- JavaTypeMapping mapping = getJpaPlatform().buildJavaTypeMappingFromAnnotation(annotationName, this);
- mapping.initializeFromResource(resourcePersistentType);
- return mapping;
+ protected JavaTypeMapping createJavaTypeMappingFromAnnotation(String annotationName, JavaResourcePersistentType jrpt) {
+ JavaTypeMapping typeMapping = getJpaPlatform().buildJavaTypeMappingFromAnnotation(annotationName, this);
+ typeMapping.initializeFromResource(jrpt);
+ return typeMapping;
}
- protected String javaMappingAnnotationName(JavaResourcePersistentType resourcePersistentType) {
- Annotation mappingAnnotation = (Annotation) resourcePersistentType.getMappingAnnotation();
+ protected String javaMappingAnnotationName(JavaResourcePersistentType jrpt) {
+ Annotation mappingAnnotation = (Annotation) jrpt.getMappingAnnotation();
if (mappingAnnotation != null) {
return mappingAnnotation.getAnnotationName();
}
return null;
}
- protected void updatePersistentAttributes(JavaResourcePersistentType resourcePersistentType) {
+ protected void updatePersistentAttributes(JavaResourcePersistentType jrpt) {
ListIterator<JavaPersistentAttribute> contextAttributes = attributes();
- Iterator<JavaResourcePersistentAttribute> resourceAttributes = resourcePersistentType.fields();
+ Iterator<JavaResourcePersistentAttribute> resourceAttributes = jrpt.fields();
if (getAccess() == AccessType.PROPERTY) {
- resourceAttributes = resourcePersistentType.properties();
+ resourceAttributes = jrpt.properties();
}
while (contextAttributes.hasNext()) {
@@ -463,11 +465,8 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
if (possibleParent != null) {
return possibleParent;
}
- JavaResourcePersistentType resourcePersistentType = getJpaProject().getJavaPersistentTypeResource(fullyQualifiedTypeName);
- if (resourcePersistentType != null) {
- return possibleParent(resourcePersistentType.getSuperClassQualifiedName());
- }
- return null;
+ JavaResourcePersistentType jrpt = getJpaProject().getJavaPersistentTypeResource(fullyQualifiedTypeName);
+ return (jrpt == null) ? null : this.possibleParent(jrpt.getSuperClassQualifiedName());
}
protected PersistentType getPersistentType(String fullyQualifiedTypeName) {
@@ -477,7 +476,7 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
//*************** Validation ******************************************
public void addToMessages(List<IMessage> messages) {
//get astRoot here to pass down
- addToMessages(messages, this.resourcePersistentType.getMember().getAstRoot());
+ addToMessages(messages, this.buildASTRoot());
}
@Override
@@ -516,4 +515,4 @@ public class GenericJavaPersistentType extends AbstractJavaJpaContextNode implem
}
}
-} \ No newline at end of file
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceUnit.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceUnit.java
index 69b4cbf0bb..395bc9c04f 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceUnit.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/context/persistence/GenericPersistenceUnit.java
@@ -17,7 +17,6 @@ import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Set;
-import org.eclipse.jdt.core.IType;
import org.eclipse.jpt.core.JpaStructureNode;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.context.AccessType;
@@ -746,10 +745,10 @@ public class GenericPersistenceUnit extends AbstractPersistenceJpaContextNode
}
protected void initializeImpliedClassRefs(XmlPersistenceUnit xmlPersistenceUnit) {
- if (getJpaProject().discoversAnnotatedClasses() && !isExcludeUnlistedClasses()) {
- for (IType type : CollectionTools.iterable(getJpaProject().annotatedClasses())) {
- if (! classIsSpecified(type.getFullyQualifiedName('.'))) {
- impliedClassRefs.add(buildClassRef(type.getFullyQualifiedName('.')));
+ if (getJpaProject().discoversAnnotatedClasses() && ! isExcludeUnlistedClasses()) {
+ for (String typeName : CollectionTools.iterable(this.getJpaProject().annotatedClassNames())) {
+ if ( ! classIsSpecified(typeName)) {
+ impliedClassRefs.add(buildClassRef(typeName));
}
}
}
@@ -928,29 +927,29 @@ public class GenericPersistenceUnit extends AbstractPersistenceJpaContextNode
protected void updateImpliedClassRefs(XmlPersistenceUnit persistenceUnit) {
Iterator<ClassRef> impliedRefs = impliedClassRefs();
- Iterator<IType> annotatedClasses = getJpaProject().annotatedClasses();
+ Iterator<String> annotatedClassNames = getJpaProject().annotatedClassNames();
- if (!isExcludeUnlistedClasses()) {
+ if ( ! isExcludeUnlistedClasses()) {
while (impliedRefs.hasNext()) {
ClassRef classRef = impliedRefs.next();
boolean updated = false;
- while (! updated && annotatedClasses.hasNext()) {
- IType annotatedClass = annotatedClasses.next();
- if (! classIsSpecified(annotatedClass.getFullyQualifiedName('.'))) {
- classRef.update(annotatedClass.getFullyQualifiedName('.'));
+ while (! updated && annotatedClassNames.hasNext()) {
+ String annotatedClassName = annotatedClassNames.next();
+ if ( ! classIsSpecified(annotatedClassName)) {
+ classRef.update(annotatedClassName);
updated = true;
}
}
- if (! annotatedClasses.hasNext() && ! updated) {
+ if (! annotatedClassNames.hasNext() && ! updated) {
removeImpliedClassRef(classRef);
}
}
- while (annotatedClasses.hasNext()) {
- IType annotatedClass = annotatedClasses.next();
- if (! classIsSpecified(annotatedClass.getFullyQualifiedName('.'))) {
- addImpliedClassRef(annotatedClass.getFullyQualifiedName('.'));
+ while (annotatedClassNames.hasNext()) {
+ String annotatedClassName = annotatedClassNames.next();
+ if ( ! classIsSpecified(annotatedClassName)) {
+ addImpliedClassRef(annotatedClassName);
}
}
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourceNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourceNode.java
index 8dd08a8f71..f0fb9e4117 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourceNode.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourceNode.java
@@ -19,12 +19,18 @@ import org.eclipse.jpt.utility.internal.model.AbstractModel;
import org.eclipse.jpt.utility.internal.model.CallbackChangeSupport;
import org.eclipse.jpt.utility.internal.model.ChangeSupport;
+/**
+ * resource containment hierarchy
+ */
public abstract class AbstractJavaResourceNode
extends AbstractModel
implements JavaResourceNode, CallbackChangeSupport.Source
{
private final JavaResourceNode parent;
+
+ // ********** construction **********
+
protected AbstractJavaResourceNode(JavaResourceNode parent) {
super();
this.checkParent(parent);
@@ -56,17 +62,31 @@ public abstract class AbstractJavaResourceNode
return new CallbackChangeSupport(this);
}
- public JavaResourceNode getParent() {
- return this.parent;
- }
+
+ // ********** JavaResourceNode implementation **********
public JpaCompilationUnit getJpaCompilationUnit() {
return this.parent.getJpaCompilationUnit();
}
+ public JavaResourceModel getResourceModel() {
+ return this.getJpaCompilationUnit().getResourceModel();
+ }
+
+
+ // ********** CallbackChangeSupport.Source implementation **********
- // **************** JavaResource implementation ****************************
+ public void aspectChanged(String aspectName) {
+ this.getJpaCompilationUnit().resourceChanged();
+ }
+
+
+ // ********** convenience methods **********
+ protected JavaResourceNode getParent() {
+ return this.parent;
+ }
+
public JpaAnnotationProvider getAnnotationProvider() {
return this.getJpaCompilationUnit().getAnnotationProvider();
}
@@ -79,15 +99,4 @@ public abstract class AbstractJavaResourceNode
return this.getJpaCompilationUnit().getAnnotationEditFormatter();
}
- public JavaResourceModel getResourceModel() {
- return this.getJpaCompilationUnit().getResourceModel();
- }
-
- public String displayString() {
- return toString();
- }
-
- public void aspectChanged(String aspectName) {
- this.getJpaCompilationUnit().resourceChanged();
- }
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourcePersistentMember.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourcePersistentMember.java
index d1d2f9a4b4..34fe50aa5e 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourcePersistentMember.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/AbstractJavaResourcePersistentMember.java
@@ -13,9 +13,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;
-import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.NormalAnnotation;
@@ -29,9 +29,11 @@ import org.eclipse.jpt.core.resource.java.JavaResourcePersistentMember;
import org.eclipse.jpt.core.resource.java.NestableAnnotation;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.core.utility.jdt.Member;
+import org.eclipse.jpt.utility.MethodSignature;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator;
+import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.SingleElementListIterator;
public abstract class AbstractJavaResourcePersistentMember<E extends Member>
@@ -60,34 +62,15 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
}
public void initialize(CompilationUnit astRoot) {
- getMember().getBodyDeclaration(astRoot).accept(initializeAnnotationVisitor(astRoot));
- this.persistable = calculatePersistability(astRoot);
+ getMember().getBodyDeclaration(astRoot).accept(this.buildInitialAnnotationVisitor(astRoot));
+ this.persistable = buildPersistable(astRoot);
}
-
- protected ASTVisitor initializeAnnotationVisitor(final CompilationUnit astRoot) {
- return new ASTVisitor() {
- @Override
- public boolean visit(SingleMemberAnnotation node) {
- return visit((org.eclipse.jdt.core.dom.Annotation) node);
- }
-
- @Override
- public boolean visit(NormalAnnotation node) {
- return visit((org.eclipse.jdt.core.dom.Annotation) node);
- }
-
+
+ protected ASTVisitor buildInitialAnnotationVisitor(CompilationUnit astRoot) {
+ return new LocalASTVisitor(astRoot, this.getMember().getBodyDeclaration(astRoot)) {
@Override
- public boolean visit(MarkerAnnotation node) {
- return visit((org.eclipse.jdt.core.dom.Annotation) node);
- }
-
- private boolean visit(org.eclipse.jdt.core.dom.Annotation node) {
- if (node.getParent() != getMember().getBodyDeclaration(astRoot)) {
- //we don't want to look at annotations for child members, only this member
- return false;
- }
- addInitialAnnotation(node, astRoot);
- return false;
+ protected void visitChildAnnotation(org.eclipse.jdt.core.dom.Annotation node) {
+ AbstractJavaResourcePersistentMember.this.addInitialAnnotation(node, this.astRoot);
}
};
}
@@ -131,7 +114,10 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
protected abstract boolean isPossibleMappingAnnotation(String annotationName);
- protected abstract boolean calculatePersistability(CompilationUnit astRoot);
+ protected boolean buildPersistable(CompilationUnit astRoot) {
+ return this.getMember().isPersistable(astRoot);
+ }
+
public Annotation getAnnotation(String annotationName) {
for (Iterator<Annotation> i = annotations(); i.hasNext(); ) {
@@ -202,11 +188,11 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
}
@SuppressWarnings("unchecked")
- protected ContainerAnnotation<NestableAnnotation> containerAnnotation(String containerAnnotationName) {
+ protected ContainerAnnotation<NestableAnnotation> getContainerAnnotation(String containerAnnotationName) {
return (ContainerAnnotation<NestableAnnotation>) getAnnotation(containerAnnotationName);
}
- protected NestableAnnotation nestableAnnotation(String nestableAnnotationName) {
+ protected NestableAnnotation getNestableAnnotation(String nestableAnnotationName) {
return (NestableAnnotation) getAnnotation(nestableAnnotationName);
}
@@ -218,7 +204,7 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
public NestableAnnotation addAnnotation(int index, String nestableAnnotationName, String containerAnnotationName) {
NestableAnnotation nestedAnnotation = (NestableAnnotation) getAnnotation(nestableAnnotationName);
- ContainerAnnotation<NestableAnnotation> containerAnnotation = containerAnnotation(containerAnnotationName);
+ ContainerAnnotation<NestableAnnotation> containerAnnotation = getContainerAnnotation(containerAnnotationName);
if (containerAnnotation != null) {
//ignore any nestableAnnotation and just add to the plural one
@@ -243,7 +229,7 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
}
public void move(int targetIndex, int sourceIndex, String containerAnnotationName) {
- move(targetIndex, sourceIndex, containerAnnotation(containerAnnotationName));
+ move(targetIndex, sourceIndex, getContainerAnnotation(containerAnnotationName));
}
protected void move(int targetIndex, int sourceIndex, ContainerAnnotation<NestableAnnotation> containerAnnotation) {
@@ -305,7 +291,7 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
}
public void removeAnnotation(int index, String nestableAnnotationName, String containerAnnotationName) {
- ContainerAnnotation<NestableAnnotation> containerAnnotation = containerAnnotation(containerAnnotationName);
+ ContainerAnnotation<NestableAnnotation> containerAnnotation = getContainerAnnotation(containerAnnotationName);
if (containerAnnotation == null) {
Annotation annotation = getAnnotation(nestableAnnotationName);
removeAnnotation(annotation);
@@ -404,11 +390,11 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
@SuppressWarnings("unchecked")
public ListIterator<NestableAnnotation> annotations(String nestableAnnotationName, String containerAnnotationName) {
- ContainerAnnotation<NestableAnnotation> containerAnnotation = containerAnnotation(containerAnnotationName);
+ ContainerAnnotation<NestableAnnotation> containerAnnotation = getContainerAnnotation(containerAnnotationName);
if (containerAnnotation != null) {
return containerAnnotation.nestedAnnotations();
}
- NestableAnnotation nestableAnnotation = nestableAnnotation(nestableAnnotationName);
+ NestableAnnotation nestableAnnotation = getNestableAnnotation(nestableAnnotationName);
if (nestableAnnotation != null) {
return new SingleElementListIterator<NestableAnnotation>(nestableAnnotation);
}
@@ -416,16 +402,16 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
}
public void updateFromJava(CompilationUnit astRoot) {
- updateAnnotations(astRoot);
- setPersistable(calculatePersistability(astRoot));
+ this.updateAnnotations(astRoot);
+ this.setPersistable(this.buildPersistable(astRoot));
}
public void resolveTypes(CompilationUnit astRoot) {
- setPersistable(calculatePersistability(astRoot));
+ this.setPersistable(this.buildPersistable(astRoot));
}
protected void updateAnnotations(CompilationUnit astRoot) {
- getMember().getBodyDeclaration(astRoot).accept(annotationVisitor(astRoot));
+ getMember().getBodyDeclaration(astRoot).accept(this.buildUpdateAnnotationVisitor(astRoot));
removeMappingAnnotationsNotInSource(astRoot);
removeAnnotationsNotInSource(astRoot);
}
@@ -446,30 +432,11 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
}
}
- protected ASTVisitor annotationVisitor(final CompilationUnit astRoot) {
- return new ASTVisitor() {
- @Override
- public boolean visit(SingleMemberAnnotation node) {
- return visit((org.eclipse.jdt.core.dom.Annotation) node);
- }
-
- @Override
- public boolean visit(NormalAnnotation node) {
- return visit((org.eclipse.jdt.core.dom.Annotation) node);
- }
-
+ protected ASTVisitor buildUpdateAnnotationVisitor(CompilationUnit astRoot) {
+ return new LocalASTVisitor(astRoot, this.getMember().getBodyDeclaration(astRoot)) {
@Override
- public boolean visit(MarkerAnnotation node) {
- return visit((org.eclipse.jdt.core.dom.Annotation) node);
- }
-
- private boolean visit(org.eclipse.jdt.core.dom.Annotation node) {
- if (node.getParent() != getMember().getBodyDeclaration(astRoot)) {
- //we don't want to look at annotations for child members, only this member
- return false;
- }
- addOrUpdateAnnotation(node, astRoot);
- return false;
+ protected void visitChildAnnotation(org.eclipse.jdt.core.dom.Annotation node) {
+ AbstractJavaResourcePersistentMember.this.addOrUpdateAnnotation(node, this.astRoot);
}
};
}
@@ -503,10 +470,14 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
}
}
- public boolean isFor(IMember iMember) {
- return getMember().wraps(iMember);
+ public boolean isFor(String memberName, int occurrence) {
+ return this.member.matches(memberName, occurrence);
}
-
+
+ public boolean isFor(MethodSignature methodSignature, int occurrence) {
+ return false;
+ }
+
public boolean isPersistable() {
return this.persistable;
}
@@ -525,7 +496,7 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
}
public TextRange fullTextRange(CompilationUnit astRoot) {
- return this.getTextRange(getMember().getBodyDeclaration(astRoot));
+ return this.getTextRange(this.getMember().getBodyDeclaration(astRoot));
}
public TextRange getTextRange(CompilationUnit astRoot) {
@@ -540,4 +511,53 @@ public abstract class AbstractJavaResourcePersistentMember<E extends Member>
return (astNode == null) ? null : new ASTNodeTextRange(astNode);
}
+ protected static <T extends JavaResourcePersistentMember> Iterator<T> persistableMembers(Iterator<T> attributes) {
+ return new FilteringIterator<T, T>(attributes) {
+ @Override
+ protected boolean accept(T attribute) {
+ return attribute.isPersistable();
+ }
+ };
+ }
+
+
+ // ********** AST visitor **********
+
+ protected abstract class LocalASTVisitor extends ASTVisitor {
+ protected final CompilationUnit astRoot;
+ protected final BodyDeclaration bodyDeclaration;
+
+ protected LocalASTVisitor(CompilationUnit astRoot, BodyDeclaration bodyDeclaration) {
+ super();
+ this.astRoot = astRoot;
+ this.bodyDeclaration = bodyDeclaration;
+ }
+
+ @Override
+ public boolean visit(SingleMemberAnnotation node) {
+ return visit_(node);
+ }
+
+ @Override
+ public boolean visit(NormalAnnotation node) {
+ return visit_(node);
+ }
+
+ @Override
+ public boolean visit(MarkerAnnotation node) {
+ return visit_(node);
+ }
+
+ protected boolean visit_(org.eclipse.jdt.core.dom.Annotation node) {
+ // ignore annotations for child members, only this member
+ if (node.getParent() == this.bodyDeclaration) {
+ this.visitChildAnnotation(node);
+ }
+ return false;
+ }
+
+ protected abstract void visitChildAnnotation(org.eclipse.jdt.core.dom.Annotation node);
+
+ }
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourceModelImpl.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourceModelImpl.java
index 2fed16234b..edef877013 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourceModelImpl.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourceModelImpl.java
@@ -24,13 +24,14 @@ import org.eclipse.jpt.core.utility.jdt.AnnotationEditFormatter;
import org.eclipse.jpt.utility.CommandExecutorProvider;
import org.eclipse.jpt.utility.internal.BitTools;
+// TODO we need access to the JPA platform
public class JavaResourceModelImpl
extends AbstractResourceModel
implements JavaResourceModel
{
private final Collection<ResourceModelListener> resourceModelListeners;
- private final JpaCompilationUnit compilationUnitResource;
+ private final JpaCompilationUnit jpaCompilationUnit;
public JavaResourceModelImpl(
@@ -39,7 +40,8 @@ public class JavaResourceModelImpl
AnnotationEditFormatter annotationEditFormatter) {
super(file);
this.resourceModelListeners = new ArrayList<ResourceModelListener>();
- this.compilationUnitResource =
+ // TODO use JPA factory, via the platform
+ this.jpaCompilationUnit =
new JpaCompilationUnitImpl(file, annotationProvider, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter, this);
}
@@ -47,9 +49,8 @@ public class JavaResourceModelImpl
return JAVA_RESOURCE_TYPE;
}
- @Override
- public JpaCompilationUnit getResource() {
- return this.compilationUnitResource;
+ public JpaCompilationUnit getJpaCompilationUnit() {
+ return this.jpaCompilationUnit;
}
public void addResourceModelChangeListener(ResourceModelListener listener) {
@@ -70,7 +71,7 @@ public class JavaResourceModelImpl
}
public void resourceChanged() {
- if (getResource() == null) {
+ if (this.jpaCompilationUnit == null) {
throw new IllegalStateException("Change events should not be fired during construction");
}
for (ResourceModelListener listener : this.resourceModelListeners) {
@@ -113,16 +114,21 @@ public class JavaResourceModelImpl
}
if (delta.getKind() == IJavaElementDelta.REMOVED) {
//we get the java notification for removal before we get the resource notification.
- //we do not need to handle this event and will get exceptions building an AstRoot if we try.
+ //we do not need to handle this event and will get exceptions building an astRoot if we try.
return;
}
- if (delta.getElement().equals(this.compilationUnitResource.getCompilationUnit())) {
+ if (delta.getElement().equals(this.jpaCompilationUnit.getCompilationUnit())) {
//TODO possibly hop on the UI thread here so that we know only 1 thread is changing our model
- this.compilationUnitResource.updateFromJava();
+ this.jpaCompilationUnit.updateFromJava();
}
}
+ public void updateFromResource() {
+ this.jpaCompilationUnit.updateFromJava();
+ }
+
public void resolveTypes() {
- this.compilationUnitResource.resolveTypes();
+ this.jpaCompilationUnit.resolveTypes();
}
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentAttributeImpl.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentAttributeImpl.java
index f788f23d18..b8a57e6296 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentAttributeImpl.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentAttributeImpl.java
@@ -11,19 +11,23 @@ package org.eclipse.jpt.core.internal.resource.java;
import java.util.Iterator;
import java.util.ListIterator;
+
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
-import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Modifier;
-import org.eclipse.jpt.core.internal.utility.jdt.JPTTools;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTFieldAttribute;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTMethodAttribute;
import org.eclipse.jpt.core.resource.java.Annotation;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
+import org.eclipse.jpt.core.resource.java.JpaCompilationUnit;
import org.eclipse.jpt.core.resource.java.NestableAnnotation;
import org.eclipse.jpt.core.utility.jdt.Attribute;
+import org.eclipse.jpt.core.utility.jdt.MethodAttribute;
+import org.eclipse.jpt.core.utility.jdt.Type;
+import org.eclipse.jpt.utility.MethodSignature;
import org.eclipse.jpt.utility.internal.CollectionTools;
public class JavaResourcePersistentAttributeImpl
@@ -41,9 +45,53 @@ public class JavaResourcePersistentAttributeImpl
private String qualifiedReferenceEntityElementTypeName;
- private boolean public_;
+ private boolean public_; // 'public' is a reserved word
- private boolean final_;
+ private boolean final_; // 'final' is a reserved word
+
+ /**
+ * construct field attribute
+ */
+ public static JavaResourcePersistentAttribute newInstance(
+ JavaResourcePersistentType parent,
+ Type declaringType,
+ String name,
+ int occurrence,
+ JpaCompilationUnit jpaCompilationUnit,
+ CompilationUnit astRoot) {
+ Attribute attribute = new JDTFieldAttribute(
+ declaringType,
+ name,
+ occurrence,
+ jpaCompilationUnit.getCompilationUnit(),
+ jpaCompilationUnit.getModifySharedDocumentCommandExecutorProvider(),
+ jpaCompilationUnit.getAnnotationEditFormatter());
+ JavaResourcePersistentAttribute field = new JavaResourcePersistentAttributeImpl(parent, attribute);
+ field.initialize(astRoot);
+ return field;
+ }
+
+ /**
+ * construct property attribute
+ */
+ public static JavaResourcePersistentAttribute newInstance(
+ JavaResourcePersistentType parent,
+ Type declaringType,
+ MethodSignature signature,
+ int occurrence,
+ JpaCompilationUnit jpaCompilationUnit,
+ CompilationUnit astRoot) {
+ Attribute attribute = JDTMethodAttribute.newInstance(
+ declaringType,
+ signature,
+ occurrence,
+ jpaCompilationUnit.getCompilationUnit(),
+ jpaCompilationUnit.getModifySharedDocumentCommandExecutorProvider(),
+ jpaCompilationUnit.getAnnotationEditFormatter());
+ JavaResourcePersistentAttribute field = new JavaResourcePersistentAttributeImpl(parent, attribute);
+ field.initialize(astRoot);
+ return field;
+ }
public JavaResourcePersistentAttributeImpl(JavaResourcePersistentType parent, Attribute attribute){
super(parent, attribute);
@@ -91,18 +139,6 @@ public class JavaResourcePersistentAttributeImpl
}
@Override
- protected boolean calculatePersistability(CompilationUnit astRoot) {
- IBinding binding = getMember().getBinding(astRoot);
- if (binding == null) {
- return false;
- }
- if (isForField()) {
- return JPTTools.fieldIsPersistable((IVariableBinding) binding);
- }
- return JPTTools.methodIsPersistablePropertyGetter((IMethodBinding) binding);
- }
-
- @Override
@SuppressWarnings("unchecked")
//overriding purely to suppress the warning you get at the class level
public ListIterator<NestableAnnotation> annotations(String nestableAnnotationName, String containerAnnotationName) {
@@ -123,6 +159,11 @@ public class JavaResourcePersistentAttributeImpl
return super.annotations();
}
+ @Override
+ public boolean isFor(MethodSignature signature, int occurrence) {
+ return ((MethodAttribute) this.getMember()).matches(signature, occurrence);
+ }
+
// ******** JavaPersistentAttributeResource implementation ********
public boolean isForField() {
@@ -248,7 +289,7 @@ public class JavaResourcePersistentAttributeImpl
}
protected boolean typeIsBasic(CompilationUnit astRoot) {
- return typeIsBasic(getMember().getTypeBinding(astRoot), astRoot.getAST());
+ return typeIsBasic(this.getMember().getTypeBinding(astRoot), astRoot.getAST());
}
protected boolean isFinal(CompilationUnit astRoot) {
@@ -262,22 +303,22 @@ public class JavaResourcePersistentAttributeImpl
}
protected String qualifiedReferenceEntityTypeName(CompilationUnit astRoot) {
- ITypeBinding typeBinding = getMember().getTypeBinding(astRoot);
- if (typeBinding == null) {
- return null;
- }
- return buildReferenceEntityTypeName(typeBinding);
+ ITypeBinding typeBinding = this.getMember().getTypeBinding(astRoot);
+ return (typeBinding == null) ? null : buildReferenceEntityTypeName(typeBinding);
}
public static String buildReferenceEntityTypeName(ITypeBinding typeBinding) {
- if (typeBinding != null && !typeBinding.isArray()) { // arrays cannot be entities
- return typeBinding.getTypeDeclaration().getQualifiedName();
+ if (typeBinding == null) {
+ return null;
+ }
+ if (typeBinding.isArray()) {
+ return null; // arrays cannot be entities
}
- return null;
+ return typeBinding.getTypeDeclaration().getQualifiedName();
}
protected String qualifiedReferenceEntityElementTypeName(CompilationUnit astRoot) {
- ITypeBinding typeBinding = getMember().getTypeBinding(astRoot);
+ ITypeBinding typeBinding = this.getMember().getTypeBinding(astRoot);
if (typeBinding == null) {
return null;
}
@@ -293,8 +334,8 @@ public class JavaResourcePersistentAttributeImpl
protected boolean typeIsContainer(CompilationUnit astRoot) {
- String typeName = buildReferenceEntityTypeName(getMember().getTypeBinding(astRoot));
- return typeName == null ? false : typeNamedIsContainer(typeName);
+ String typeName = buildReferenceEntityTypeName(this.getMember().getTypeBinding(astRoot));
+ return (typeName == null) ? false : typeNamedIsContainer(typeName);
}
/**
@@ -313,11 +354,8 @@ public class JavaResourcePersistentAttributeImpl
};
protected String qualifiedTypeName(CompilationUnit astRoot) {
- ITypeBinding typeBinding = getMember().getTypeBinding(astRoot);
- if (typeBinding == null) {
- return null;
- }
- return typeBinding.getQualifiedName();
+ ITypeBinding typeBinding = this.getMember().getTypeBinding(astRoot);
+ return (typeBinding == null) ? null : typeBinding.getQualifiedName();
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentTypeImpl.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentTypeImpl.java
index fd4e63e5e7..5f8d4272db 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentTypeImpl.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JavaResourcePersistentTypeImpl.java
@@ -9,91 +9,154 @@
******************************************************************************/
package org.eclipse.jpt.core.internal.resource.java;
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.Vector;
-import org.eclipse.jdt.core.IField;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jpt.core.internal.utility.jdt.JDTFieldAttribute;
-import org.eclipse.jpt.core.internal.utility.jdt.JDTMethodAttribute;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.Modifier;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
import org.eclipse.jpt.core.internal.utility.jdt.JDTType;
-import org.eclipse.jpt.core.internal.utility.jdt.JPTTools;
import org.eclipse.jpt.core.resource.java.AccessType;
import org.eclipse.jpt.core.resource.java.Annotation;
-import org.eclipse.jpt.core.resource.java.JavaResourceNode;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
+import org.eclipse.jpt.core.resource.java.JpaCompilationUnit;
import org.eclipse.jpt.core.resource.java.NestableAnnotation;
-import org.eclipse.jpt.core.utility.jdt.AnnotationEditFormatter;
-import org.eclipse.jpt.core.utility.jdt.Attribute;
import org.eclipse.jpt.core.utility.jdt.Type;
-import org.eclipse.jpt.utility.CommandExecutorProvider;
+import org.eclipse.jpt.utility.MethodSignature;
import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.Counter;
import org.eclipse.jpt.utility.internal.iterators.CloneIterator;
+import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
public class JavaResourcePersistentTypeImpl
extends AbstractJavaResourcePersistentMember<Type>
implements JavaResourcePersistentType
-{
+{
+ private String qualifiedName;
+
+ private String name;
+
+ private String superClassQualifiedName;
+
+ private boolean abstract_; // 'abstract' is a reserved word
+
/**
- * store all member types including those that aren't persistable so we can include validation errors.
+ * store all member types including those that aren't persistable so we can
+ * generate validation errors
*/
- private final Collection<JavaResourcePersistentType> nestedTypes;
-
- private final Collection<JavaResourcePersistentAttribute> attributes;
-
+ private final Vector<JavaResourcePersistentType> nestedTypes;
+
+ private final Vector<JavaResourcePersistentAttribute> fields;
+
+ private final Vector<JavaResourcePersistentAttribute> methods;
+
private AccessType accessType;
-
- private String superClassQualifiedName;
-
- private String qualifiedName;
-
- private String name;
-
- private boolean isAbstract;
-
- public JavaResourcePersistentTypeImpl(JavaResourceNode parent, Type type){
- super(parent, type);
- this.nestedTypes = new ArrayList<JavaResourcePersistentType>();
- this.attributes = new ArrayList<JavaResourcePersistentAttribute>();
+
+
+ // ********** construction **********
+
+ /**
+ * build top-level persistent type
+ */
+ // TODO use JPA factory
+ public static JavaResourcePersistentType newInstance(
+ JpaCompilationUnit jpaCompilationUnit,
+ TypeDeclaration typeDeclaration,
+ CompilationUnit astRoot) {
+ Type type = new JDTType(
+ typeDeclaration,
+ jpaCompilationUnit.getCompilationUnit(),
+ jpaCompilationUnit.getModifySharedDocumentCommandExecutorProvider(),
+ jpaCompilationUnit.getAnnotationEditFormatter());
+ JavaResourcePersistentType jrpt = new JavaResourcePersistentTypeImpl(jpaCompilationUnit, type);
+ jrpt.initialize(astRoot);
+ return jrpt;
+ }
+
+ /**
+ * build nested persistent type
+ */
+ // TODO use JPA factory
+ protected static JavaResourcePersistentType newInstance(
+ JpaCompilationUnit jpaCompilationUnit,
+ Type declaringType,
+ TypeDeclaration typeDeclaration,
+ int occurrence,
+ CompilationUnit astRoot) {
+ Type type = new JDTType(
+ declaringType,
+ typeDeclaration,
+ occurrence,
+ jpaCompilationUnit.getCompilationUnit(),
+ jpaCompilationUnit.getModifySharedDocumentCommandExecutorProvider(),
+ jpaCompilationUnit.getAnnotationEditFormatter());
+ JavaResourcePersistentType jrpt = new JavaResourcePersistentTypeImpl(jpaCompilationUnit, type);
+ jrpt.initialize(astRoot);
+ return jrpt;
+ }
+
+ public JavaResourcePersistentTypeImpl(JpaCompilationUnit jpaCompilationUnit, Type type) {
+ super(jpaCompilationUnit, type);
+ this.nestedTypes = new Vector<JavaResourcePersistentType>();
+ this.fields = new Vector<JavaResourcePersistentAttribute>();
+ this.methods = new Vector<JavaResourcePersistentAttribute>();
}
@Override
public void initialize(CompilationUnit astRoot) {
super.initialize(astRoot);
- this.qualifiedName = this.qualifiedName(astRoot);
- this.name = this.name(astRoot);
+ this.qualifiedName = this.buildQualifiedName(astRoot);
+ this.name = this.buildName(astRoot);
+ this.superClassQualifiedName = this.buildSuperClassQualifiedName(astRoot);
+ this.abstract_ = this.buildAbstract(astRoot);
this.initializeNestedTypes(astRoot);
- this.initializePersistentProperties(astRoot);
- this.accessType = this.calculateAccessType();
- this.superClassQualifiedName = this.superClassQualifiedName(astRoot);
- this.isAbstract = this.isAbstract(astRoot);
+ this.initializeFields(astRoot);
+ this.initializeMethods(astRoot);
+ this.accessType = this.buildAccessType();
}
-
+
protected void initializeNestedTypes(CompilationUnit astRoot) {
- for (IType declaredType : getMember().jdtTypes()) {
- this.nestedTypes.add(buildJavaResourcePersistentType(declaredType, astRoot));
+ CounterMap counters = new CounterMap();
+ for (TypeDeclaration td : this.getMember().getTypes(astRoot)) {
+ String tdName = td.getName().getFullyQualifiedName();
+ int occurrence = counters.increment(tdName);
+ this.nestedTypes.add(this.buildNestedType(td, occurrence, astRoot));
}
}
-
- protected void initializePersistentProperties(CompilationUnit astRoot) {
- for (IField field : getMember().jdtFields()) {
- this.attributes.add(createJavaPersistentAttribute(field, astRoot));
+
+ protected void initializeFields(CompilationUnit astRoot) {
+ CounterMap counters = new CounterMap();
+ for (FieldDeclaration fieldDeclaration : this.getMember().getFields(astRoot)) {
+ for (VariableDeclarationFragment fragment : fragments(fieldDeclaration)) {
+ String fieldName = fragment.getName().getFullyQualifiedName();
+ int occurrence = counters.increment(fieldName);
+ this.fields.add(this.buildField(fieldName, occurrence, astRoot));
+ }
}
- for (IMethod method : getMember().jdtMethods()) {
- this.attributes.add(createJavaPersistentAttribute(method, astRoot));
+ }
+
+ protected void initializeMethods(CompilationUnit astRoot) {
+ CounterMap counters = new CounterMap();
+ for (MethodDeclaration methodDeclaration : this.getMember().getMethods(astRoot)) {
+ MethodSignature signature = JDTTools.buildMethodSignature(methodDeclaration);
+ int occurrence = counters.increment(signature);
+ this.methods.add(this.buildMethod(signature, occurrence, astRoot));
}
}
-
- // ******** AbstractJavaPersistentResource implementation ********
+
+
+ // ********** AbstractJavaResourcePersistentMember implementation **********
@Override
protected Annotation buildMappingAnnotation(String mappingAnnotationName) {
@@ -131,12 +194,6 @@ public class JavaResourcePersistentTypeImpl
}
@Override
- protected boolean calculatePersistability(CompilationUnit astRoot) {
- return JPTTools.typeIsPersistable(getMember().getBinding(astRoot));
- }
-
-
- @Override
@SuppressWarnings("unchecked")
//overriding purely to suppress the warning you get at the class level
public ListIterator<NestableAnnotation> annotations(String nestableAnnotationName, String containerAnnotationName) {
@@ -157,290 +214,388 @@ public class JavaResourcePersistentTypeImpl
return super.annotations();
}
-
- // ******** JavaPersistentTypeResource implementation ********
+ @Override
+ public void resolveTypes(CompilationUnit astRoot) {
+ super.resolveTypes(astRoot);
+
+ this.setSuperClassQualifiedName(this.buildSuperClassQualifiedName(astRoot));
+
+ for (Iterator<JavaResourcePersistentAttribute> stream = this.fields_(); stream.hasNext(); ) {
+ stream.next().resolveTypes(astRoot);
+ }
+
+ // a new type can trigger a method parameter type to be a resolved,
+ // fully-qualified name, so we need to rebuild our list of methods:
+ // "setFoo(Foo)" is not the same as "setFoo(com.bar.Foo)"
+ // and, vice-versa, a removed type can "unresolve" a parameter type
+ this.updateMethods(astRoot);
+
+ for (Iterator<JavaResourcePersistentAttribute> stream = this.methods_(); stream.hasNext(); ) {
+ stream.next().resolveTypes(astRoot);
+ }
+ for (Iterator<JavaResourcePersistentType> stream = this.nestedTypes_(); stream.hasNext(); ) {
+ stream.next().resolveTypes(astRoot);
+ }
+ }
+
+ @Override
+ public void toString(StringBuilder sb) {
+ sb.append(this.name);
+ }
+
+
+ // ******** JavaResourcePersistentType implementation ********
+
public JavaResourcePersistentType getJavaPersistentTypeResource(String fullyQualifiedTypeName) {
- if (getQualifiedName().equals(fullyQualifiedTypeName)) {
+ // TODO not sure why a null name is coming through here... ~bjv
+// if (fullyQualifiedTypeName.equals(this.getQualifiedName())) {
+ if (this.getQualifiedName().equals(fullyQualifiedTypeName)) {
return this;
}
- for (JavaResourcePersistentType jptr : CollectionTools.iterable(nestedTypes())) {
- if (jptr.getQualifiedName().equals(fullyQualifiedTypeName)) {
- return jptr;
+ for (Iterator<JavaResourcePersistentType> stream = this.nestedTypes(); stream.hasNext(); ) {
+ JavaResourcePersistentType jrpt = stream.next();
+ // recurse
+ JavaResourcePersistentType nestedJRPT = jrpt.getJavaPersistentTypeResource(fullyQualifiedTypeName);
+ if (nestedJRPT != null) {
+ return nestedJRPT;
}
}
return null;
}
+ /**
+ * check only persistable attributes
+ */
+ public boolean hasAnyAttributeAnnotations() {
+ for (Iterator<JavaResourcePersistentAttribute> stream = this.attributes(); stream.hasNext(); ) {
+ if (stream.next().hasAnyAnnotation()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ // ********** nested types **********
+
+ /**
+ * return only persistable nested types
+ */
public Iterator<JavaResourcePersistentType> nestedTypes() {
//TODO since we are filtering how do we handle the case where a type becomes persistable?
//what kind of change notificiation for that case?
- return new FilteringIterator<JavaResourcePersistentType, JavaResourcePersistentType>(new CloneIterator<JavaResourcePersistentType>(this.nestedTypes)) {
+ return new FilteringIterator<JavaResourcePersistentType, JavaResourcePersistentType>(this.nestedTypes_()) {
@Override
- protected boolean accept(JavaResourcePersistentType o) {
- return o.isPersistable();
+ protected boolean accept(JavaResourcePersistentType jrpt) {
+ return jrpt.isPersistable();
}
};
}
-
- protected JavaResourcePersistentType nestedTypeFor(IType type) {
- for (JavaResourcePersistentType nestedType : this.nestedTypes) {
- if (nestedType.isFor(type)) {
- return nestedType;
- }
- }
- return null;
- }
-
- protected JavaResourcePersistentType addNestedType(IType nestedType, CompilationUnit astRoot) {
- JavaResourcePersistentType persistentType = buildJavaResourcePersistentType(nestedType, astRoot);
- addNestedType(persistentType);
- return persistentType;
+
+ /**
+ * *all* nested types
+ */
+ protected Iterator<JavaResourcePersistentType> nestedTypes_() {
+ return new CloneIterator<JavaResourcePersistentType>(this.nestedTypes);
}
protected void addNestedType(JavaResourcePersistentType nestedType) {
- addItemToCollection(nestedType, this.nestedTypes, NESTED_TYPES_COLLECTION);
+ this.addItemToCollection(nestedType, this.nestedTypes, NESTED_TYPES_COLLECTION);
}
-
+
protected void removeNestedType(JavaResourcePersistentType nestedType) {
- removeItemFromCollection(nestedType, this.nestedTypes, NESTED_TYPES_COLLECTION);
+ this.removeItemFromCollection(nestedType, this.nestedTypes, NESTED_TYPES_COLLECTION);
}
-
- protected JavaResourcePersistentType buildJavaResourcePersistentType(IType nestedType, CompilationUnit astRoot) {
- return buildJavaResourcePersistentType(this, nestedType, getModifySharedDocumentCommandExecutorProvider(), getAnnotationEditFormatter(), astRoot);
- }
-
- public static JavaResourcePersistentType buildJavaResourcePersistentType(
- JavaResourceNode parent,
- IType nestedType,
- CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
- AnnotationEditFormatter annotationEditFormatter,
- CompilationUnit astRoot) {
-
- Type type = new JDTType(nestedType, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
- JavaResourcePersistentTypeImpl javaPersistentType = new JavaResourcePersistentTypeImpl(parent, type);
- javaPersistentType.initialize(astRoot);
- return javaPersistentType;
+
+ protected void removeNestedTypes(Collection<JavaResourcePersistentType> remove) {
+ this.removeItemsFromCollection(remove, this.nestedTypes, NESTED_TYPES_COLLECTION);
}
-
- public Iterator<JavaResourcePersistentAttribute> attributes() {
- //TODO since we are filtering how do we handle the case where an attribute becomes persistable?
- //what kind of change notificiation for that case?
- return new FilteringIterator<JavaResourcePersistentAttribute, JavaResourcePersistentAttribute>(new CloneIterator<JavaResourcePersistentAttribute>(this.attributes)) {
- @Override
- protected boolean accept(JavaResourcePersistentAttribute o) {
- return o.isPersistable();
+
+ protected JavaResourcePersistentType getNestedType(String typeName, int occurrence) {
+ for (Iterator<JavaResourcePersistentType> stream = this.nestedTypes_(); stream.hasNext(); ) {
+ JavaResourcePersistentType nestedType = stream.next();
+ if (nestedType.isFor(typeName, occurrence)) {
+ return nestedType;
}
- };
+ }
+ return null;
}
-
- public Iterator<JavaResourcePersistentAttribute> fields() {
- return new FilteringIterator<JavaResourcePersistentAttribute, JavaResourcePersistentAttribute>(attributes()) {
- @Override
- protected boolean accept(JavaResourcePersistentAttribute o) {
- return o.isForField();
- }
- };
+
+
+ // ********** attributes **********
+
+ /**
+ * return only persistable attributes
+ */
+ // TODO since we are filtering, how do we handle the case where an attribute becomes persistable?
+ // what kind of change notification for that case?
+ public Iterator<JavaResourcePersistentAttribute> attributes() {
+ return persistableMembers(this.attributes_());
}
-
- public Iterator<JavaResourcePersistentAttribute> properties() {
- return new FilteringIterator<JavaResourcePersistentAttribute, JavaResourcePersistentAttribute>(attributes()) {
- @Override
- protected boolean accept(JavaResourcePersistentAttribute o) {
- return o.isForProperty();
- }
- };
+
+ /**
+ * *all* fields and methods
+ */
+ @SuppressWarnings("unchecked")
+ protected Iterator<JavaResourcePersistentAttribute> attributes_() {
+ return new CompositeIterator<JavaResourcePersistentAttribute>(this.fields_(), this.methods_());
}
- protected JavaResourcePersistentAttribute addAttribute(IMember jdtMember, CompilationUnit astRoot) {
- JavaResourcePersistentAttribute persistentAttribute = createJavaPersistentAttribute(jdtMember, astRoot);
- addAttribute(persistentAttribute);
- return persistentAttribute;
+
+ // ********** fields **********
+
+ /**
+ * return only persistable fields
+ */
+ public Iterator<JavaResourcePersistentAttribute> fields() {
+ return persistableMembers(this.fields_());
}
- protected void addAttribute(JavaResourcePersistentAttribute attribute) {
- addItemToCollection(attribute, this.attributes, ATTRIBUTES_COLLECTION);
+ /**
+ * *all* fields
+ */
+ protected Iterator<JavaResourcePersistentAttribute> fields_() {
+ return new CloneIterator<JavaResourcePersistentAttribute>(this.fields);
}
- protected JavaResourcePersistentAttribute createJavaPersistentAttribute(IMember member, CompilationUnit astRoot) {
- Attribute attribute = null;
- if (member instanceof IField) {
- attribute = new JDTFieldAttribute((IField) member, this.getModifySharedDocumentCommandExecutorProvider(), this.getAnnotationEditFormatter());
- }
- else if (member instanceof IMethod) {
- attribute = new JDTMethodAttribute((IMethod) member, this.getModifySharedDocumentCommandExecutorProvider(), this.getAnnotationEditFormatter());
- }
- else {
- throw new IllegalArgumentException();
- }
- JavaResourcePersistentAttribute javaPersistentAttribute = new JavaResourcePersistentAttributeImpl(this, attribute);
- javaPersistentAttribute.initialize(astRoot);
- return javaPersistentAttribute;
+ protected void addField(JavaResourcePersistentAttribute attribute) {
+ this.addItemToCollection(attribute, this.fields, ATTRIBUTES_COLLECTION);
}
-
- protected void removeAttribute(JavaResourcePersistentAttribute attribute) {
- removeItemFromCollection(attribute, this.attributes, ATTRIBUTES_COLLECTION);
+
+ protected void removeField(JavaResourcePersistentAttribute attribute) {
+ this.removeItemFromCollection(attribute, this.fields, ATTRIBUTES_COLLECTION);
}
-
- protected JavaResourcePersistentAttribute attributeFor(IMember member) {
- for (JavaResourcePersistentAttribute persistentAttribute : this.attributes) {
- if (persistentAttribute.isFor(member)) {
- return persistentAttribute;
+
+ protected void removeFields(Collection<JavaResourcePersistentAttribute> remove) {
+ this.removeItemsFromCollection(remove, this.fields, ATTRIBUTES_COLLECTION);
+ }
+
+ protected JavaResourcePersistentAttribute getField(String fieldName, int occurrence) {
+ for (Iterator<JavaResourcePersistentAttribute> stream = this.fields_(); stream.hasNext(); ) {
+ JavaResourcePersistentAttribute field = stream.next();
+ if (field.isFor(fieldName, occurrence)) {
+ return field;
}
}
return null;
}
-
- public AccessType getAccess() {
- return this.accessType;
+
+
+ // ********** methods **********
+
+ /**
+ * return only persistable properties
+ */
+ public Iterator<JavaResourcePersistentAttribute> properties() {
+ return persistableMembers(this.methods_());
}
-
- //seems we could have a public changeAccess() api which would
- //move all annotations from fields to their corresponding methods or vice versa
- //though of course it's more complicated than that since what if the
- //corresponding field/method does not exist?
- //making this internal since it should only be set based on changes in the source, the
- //context model should not need to set this
- protected void setAccess(AccessType newAccess) {
- AccessType oldAccess = this.accessType;
- this.accessType = newAccess;
- firePropertyChanged(ACCESS_PROPERTY, oldAccess, newAccess);
+
+ /**
+ * *all* methods
+ */
+ protected Iterator<JavaResourcePersistentAttribute> methods_() {
+ return new CloneIterator<JavaResourcePersistentAttribute>(this.methods);
}
- public String getSuperClassQualifiedName() {
- return this.superClassQualifiedName;
+ protected void addMethod(JavaResourcePersistentAttribute attribute) {
+ this.addItemToCollection(attribute, this.methods, ATTRIBUTES_COLLECTION);
}
-
- private void setSuperClassQualifiedName(String newSuperClassQualifiedName) {
- String oldSuperClassQualifiedName = this.superClassQualifiedName;
- this.superClassQualifiedName = newSuperClassQualifiedName;
- firePropertyChanged(SUPER_CLASS_QUALIFIED_NAME_PROPERTY, oldSuperClassQualifiedName, newSuperClassQualifiedName);
+
+ protected void removeMethod(JavaResourcePersistentAttribute attribute) {
+ this.removeItemFromCollection(attribute, this.methods, ATTRIBUTES_COLLECTION);
}
+ protected void removeMethods(Collection<JavaResourcePersistentAttribute> remove) {
+ this.removeItemsFromCollection(remove, this.methods, ATTRIBUTES_COLLECTION);
+ }
+
+ protected JavaResourcePersistentAttribute getMethod(MethodSignature signature, int occurrence) {
+ for (Iterator<JavaResourcePersistentAttribute> stream = this.methods_(); stream.hasNext(); ) {
+ JavaResourcePersistentAttribute method = stream.next();
+ if (method.isFor(signature, occurrence)) {
+ return method;
+ }
+ }
+ return null;
+ }
+
+
+ // ********** simple instance variables **********
+
public String getQualifiedName() {
return this.qualifiedName;
}
-
- protected void setQualifiedName(String newQualifiedName) {
- String oldQualifiedName = this.qualifiedName;
- this.qualifiedName = newQualifiedName;
- firePropertyChanged(QUALIFIED_NAME_PROPERTY, oldQualifiedName, newQualifiedName);
+
+ protected void setQualifiedName(String qualifiedName) {
+ String old = this.qualifiedName;
+ this.qualifiedName = qualifiedName;
+ this.firePropertyChanged(QUALIFIED_NAME_PROPERTY, old, qualifiedName);
}
-
+
public String getName() {
return this.name;
}
-
- protected void setName(String newName) {
- String oldName = this.name;
- this.name = newName;
- firePropertyChanged(NAME_PROPERTY, oldName, newName);
+
+ protected void setName(String name) {
+ String old = this.name;
+ this.name = name;
+ this.firePropertyChanged(NAME_PROPERTY, old, name);
}
-
- public boolean isAbstract() {
- return this.isAbstract;
+
+ public String getSuperClassQualifiedName() {
+ return this.superClassQualifiedName;
}
-
- protected void setAbstract(boolean newAbstract) {
- boolean oldAbstract = this.isAbstract;
- this.isAbstract = newAbstract;
- firePropertyChanged(ABSTRACT_PROPERTY, oldAbstract, newAbstract);
+
+ protected void setSuperClassQualifiedName(String superClassQualifiedName) {
+ String old = this.superClassQualifiedName;
+ this.superClassQualifiedName = superClassQualifiedName;
+ this.firePropertyChanged(SUPER_CLASS_QUALIFIED_NAME_PROPERTY, old, superClassQualifiedName);
}
-
- @Override
- public void updateFromJava(CompilationUnit astRoot) {
- super.updateFromJava(astRoot);
- this.setQualifiedName(this.qualifiedName(astRoot));
- this.setName(this.name(astRoot));
- this.updateNestedTypes(astRoot);
- this.updatePersistentAttributes(astRoot);
- this.setAccess(this.calculateAccessType());
- this.setSuperClassQualifiedName(this.superClassQualifiedName(astRoot));
- this.setAbstract(isAbstract(astRoot));
+
+ public boolean isAbstract() {
+ return this.abstract_;
}
-
- @Override
- public void resolveTypes(CompilationUnit astRoot) {
- super.resolveTypes(astRoot);
- this.setSuperClassQualifiedName(this.superClassQualifiedName(astRoot));
- for (JavaResourcePersistentAttribute attribute : this.attributes) {
- attribute.resolveTypes(astRoot);
- }
- for (JavaResourcePersistentType persistentType : this.nestedTypes) {
- persistentType.resolveTypes(astRoot);
- }
+ protected void setAbstract(boolean abstract_) {
+ boolean old = this.abstract_;
+ this.abstract_ = abstract_;
+ this.firePropertyChanged(ABSTRACT_PROPERTY, old, abstract_);
}
-
- protected boolean isAbstract(CompilationUnit astRoot) {
- return JPTTools.typeIsAbstract(getMember().getBinding(astRoot));
+
+ public AccessType getAccess() {
+ return this.accessType;
}
- protected String qualifiedName(CompilationUnit astRoot) {
- return getMember().getBinding(astRoot).getQualifiedName();
+ // TODO
+ //seems we could have a public changeAccess() api which would
+ //move all annotations from fields to their corresponding methods or vice versa
+ //though of course it's more complicated than that since what if the
+ //corresponding field/method does not exist?
+ //making this internal since it should only be set based on changes in the source, the
+ //context model should not need to set this
+ protected void setAccess(AccessType accessType) {
+ AccessType old = this.accessType;
+ this.accessType = accessType;
+ this.firePropertyChanged(ACCESS_PROPERTY, old, accessType);
}
-
- protected String name(CompilationUnit astRoot) {
- return getMember().getBinding(astRoot).getName();
+
+
+ // ********** update from Java **********
+
+ @Override
+ public void updateFromJava(CompilationUnit astRoot) {
+ super.updateFromJava(astRoot);
+ this.setQualifiedName(this.buildQualifiedName(astRoot));
+ this.setName(this.buildName(astRoot));
+ this.setSuperClassQualifiedName(this.buildSuperClassQualifiedName(astRoot));
+ this.setAbstract(this.buildAbstract(astRoot));
+ this.updateNestedTypes(astRoot);
+ this.updateFields(astRoot);
+ this.updateMethods(astRoot);
+ this.setAccess(this.buildAccessType());
}
-
+
protected void updateNestedTypes(CompilationUnit astRoot) {
- IType[] declaredTypes = getMember().jdtTypes();
-
- List<JavaResourcePersistentType> nestedTypesToRemove = new ArrayList<JavaResourcePersistentType>(this.nestedTypes);
- for (IType declaredType : declaredTypes) {
- JavaResourcePersistentType nestedType = nestedTypeFor(declaredType);
+ CounterMap counters = new CounterMap();
+ @SuppressWarnings("unchecked")
+ Vector<JavaResourcePersistentType> nestedTypesToRemove = (Vector<JavaResourcePersistentType>) this.nestedTypes.clone();
+ for (TypeDeclaration typeDeclaration : this.getMember().getTypes(astRoot)) {
+ String tdName = typeDeclaration.getName().getFullyQualifiedName();
+ int occurrence = counters.increment(tdName);
+
+ JavaResourcePersistentType nestedType = this.getNestedType(tdName, occurrence);
if (nestedType == null) {
- nestedType = addNestedType(declaredType, astRoot);
- }
- else {
+ this.addNestedType(this.buildNestedType(typeDeclaration, occurrence, astRoot));
+ } else {
nestedTypesToRemove.remove(nestedType);
+ nestedType.updateFromJava(astRoot);
}
- nestedType.updateFromJava(astRoot);
}
- for (JavaResourcePersistentType nestedType : nestedTypesToRemove) {
- removeNestedType(nestedType);
+ this.removeNestedTypes(nestedTypesToRemove);
+ }
+
+ protected void updateFields(CompilationUnit astRoot) {
+ CounterMap counters = new CounterMap();
+ @SuppressWarnings("unchecked")
+ Vector<JavaResourcePersistentAttribute> fieldsToRemove = (Vector<JavaResourcePersistentAttribute>) this.fields.clone();
+ for (FieldDeclaration fieldDeclaration : this.getMember().getFields(astRoot)) {
+ for (VariableDeclarationFragment fragment : fragments(fieldDeclaration)) {
+ String fieldName = fragment.getName().getFullyQualifiedName();
+ int occurrence = counters.increment(fieldName);
+
+ JavaResourcePersistentAttribute field = this.getField(fieldName, occurrence);
+ if (field == null) {
+ this.addField(this.buildField(fieldName, occurrence, astRoot));
+ } else {
+ fieldsToRemove.remove(field);
+ field.updateFromJava(astRoot);
+ }
+ }
}
+ this.removeFields(fieldsToRemove);
}
-
- protected void updatePersistentAttributes(CompilationUnit astRoot) {
- List<JavaResourcePersistentAttribute> persistentAttributesToRemove = new ArrayList<JavaResourcePersistentAttribute>(this.attributes);
- updatePersistentFields(astRoot, persistentAttributesToRemove);
- updatePersistentProperties(astRoot, persistentAttributesToRemove);
- for (JavaResourcePersistentAttribute persistentAttribute : persistentAttributesToRemove) {
- removeAttribute(persistentAttribute);
+
+ protected void updateMethods(CompilationUnit astRoot) {
+ CounterMap counters = new CounterMap();
+ @SuppressWarnings("unchecked")
+ Vector<JavaResourcePersistentAttribute> methodsToRemove = (Vector<JavaResourcePersistentAttribute>) this.methods.clone();
+ for (MethodDeclaration methodDeclaration : this.getMember().getMethods(astRoot)) {
+ MethodSignature signature = JDTTools.buildMethodSignature(methodDeclaration);
+ int occurrence = counters.increment(signature);
+
+ JavaResourcePersistentAttribute method = this.getMethod(signature, occurrence);
+ if (method == null) {
+ this.addMethod(this.buildMethod(signature, occurrence, astRoot));
+ } else {
+ methodsToRemove.remove(method);
+ method.updateFromJava(astRoot);
+ }
}
+ this.removeMethods(methodsToRemove);
}
-
- protected void updatePersistentFields(CompilationUnit astRoot, List<JavaResourcePersistentAttribute> persistentAttributesToRemove) {
- updatePersistentAttributes(astRoot, persistentAttributesToRemove, getMember().jdtFields());
+
+
+ // ********** building state from AST **********
+
+ protected String buildQualifiedName(CompilationUnit astRoot) {
+ return this.getMember().getBinding(astRoot).getQualifiedName();
}
- protected void updatePersistentProperties(CompilationUnit astRoot, List<JavaResourcePersistentAttribute> persistentAttributesToRemove) {
- updatePersistentAttributes(astRoot, persistentAttributesToRemove, getMember().jdtMethods());
+ protected String buildName(CompilationUnit astRoot) {
+ return this.getMember().getBinding(astRoot).getName();
}
- protected void updatePersistentAttributes(CompilationUnit astRoot, List<JavaResourcePersistentAttribute> persistentAttributesToRemove, IMember[] members) {
- for (IMember member : members) {
- JavaResourcePersistentAttribute persistentAttribute = attributeFor(member);
- if (persistentAttribute == null) {
- persistentAttribute = addAttribute(member, astRoot);
- }
- else {
- persistentAttributesToRemove.remove(persistentAttribute);
- }
- persistentAttribute.updateFromJava(astRoot);
+ protected String buildSuperClassQualifiedName(CompilationUnit astRoot) {
+ ITypeBinding typeBinding = this.getMember().getBinding(astRoot);
+ if (typeBinding == null) {
+ return null;
}
- }
-
- public boolean hasAnyAttributeAnnotations() {
- for (JavaResourcePersistentAttribute attribute : CollectionTools.iterable(attributes())) {
- if (attribute.hasAnyAnnotation()) {
- return true;
- }
+ ITypeBinding superClassTypeBinding = typeBinding.getSuperclass();
+ if (superClassTypeBinding == null) {
+ return null;
}
- return false;
+ return superClassTypeBinding.getQualifiedName();
}
-
+
+ protected boolean buildAbstract(CompilationUnit astRoot) {
+ return Modifier.isAbstract(this.getMember().getBinding(astRoot).getModifiers());
+ }
+
+ // TODO use JPA factory
+ protected JavaResourcePersistentType buildNestedType(TypeDeclaration nestedTypeDeclaration, int occurrence, CompilationUnit astRoot) {
+ return newInstance(this.getJpaCompilationUnit(), this.getMember(), nestedTypeDeclaration, occurrence, astRoot);
+ }
+
+ // TODO use JPA factory
+ protected JavaResourcePersistentAttribute buildField(String fieldName, int occurrence, CompilationUnit astRoot) {
+ return JavaResourcePersistentAttributeImpl.newInstance(this, this.getMember(), fieldName, occurrence, this.getJpaCompilationUnit(), astRoot);
+ }
+
+ // TODO use JPA factory
+ protected JavaResourcePersistentAttribute buildMethod(MethodSignature signature, int occurrence, CompilationUnit astRoot) {
+ return JavaResourcePersistentAttributeImpl.newInstance(this, this.getMember(), signature, occurrence, this.getJpaCompilationUnit(), astRoot);
+ }
+
/**
* Return the AccessType currently implied by the Java source code:
* - if only Fields are annotated => FIELD
@@ -451,7 +606,7 @@ public class JavaResourcePersistentTypeImpl
* - and properties exist, but no fields exist => PROPERTY
* - and neither fields nor properties exist => null at this level (FIELD in the context model)
*/
- private AccessType calculateAccessType() {
+ protected AccessType buildAccessType() {
boolean hasPersistableFields = false;
boolean hasPersistableProperties = false;
for (JavaResourcePersistentAttribute field : CollectionTools.iterable(fields())) {
@@ -475,22 +630,34 @@ public class JavaResourcePersistentTypeImpl
//no annotations exist, access is null at the resource model level
return null;
}
-
- private String superClassQualifiedName(CompilationUnit astRoot) {
- ITypeBinding typeBinding = getMember().getBinding(astRoot);
- if (typeBinding == null) {
- return null;
- }
- ITypeBinding superClassTypeBinding = typeBinding.getSuperclass();
- if (superClassTypeBinding == null) {
- return null;
- }
- return superClassTypeBinding.getQualifiedName();
+
+
+ // ********** static methods **********
+
+ // minimize scope of suppressed warnings
+ @SuppressWarnings("unchecked")
+ protected static List<VariableDeclarationFragment> fragments(FieldDeclaration fd) {
+ return fd.fragments();
}
-
- @Override
- public void toString(StringBuilder sb) {
- sb.append(getName());
+
+
+ // ********** StringCounter **********
+
+ protected static class CounterMap {
+ HashMap<Object, Counter> counters = new HashMap<Object, Counter>();
+
+ /**
+ * Return the incremented count for the specified object.
+ */
+ int increment(Object o) {
+ Counter counter = this.counters.get(o);
+ if (counter == null) {
+ counter = new Counter();
+ this.counters.put(o, counter);
+ }
+ counter.increment();
+ return counter.count();
+ }
}
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JpaCompilationUnitImpl.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JpaCompilationUnitImpl.java
index 9516cc2618..a4697ebf26 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JpaCompilationUnitImpl.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JpaCompilationUnitImpl.java
@@ -9,12 +9,16 @@
******************************************************************************/
package org.eclipse.jpt.core.internal.resource.java;
+import java.util.List;
+
import org.eclipse.core.resources.IFile;
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.ASTNode;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jpt.core.JpaAnnotationProvider;
import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
import org.eclipse.jpt.core.resource.java.JavaResourceModel;
@@ -29,61 +33,67 @@ public class JpaCompilationUnitImpl
implements JpaCompilationUnit
{
protected final JpaAnnotationProvider annotationProvider;
-
+
protected final CommandExecutorProvider modifySharedDocumentCommandExecutorProvider;
-
+
protected final AnnotationEditFormatter annotationEditFormatter;
-
+
+ protected final JavaResourceModel javaResourceModel;
+
protected final ICompilationUnit compilationUnit;
-
+
/**
- * The primary type of the CompilationUnit. Not going to handle
- * multiple Types defined in a compilation unit. Entities must have
- * a public/protected no-arg constructor and there is no way to access
- * it in a non-public/protected class.
+ * The primary type of the AST compilation unit. We are not going to handle
+ * multiple types defined in a single compilation unit. Entities must have
+ * a public/protected no-arg constructor, and there is no way to access
+ * the constructor in a package class (which is what all top-level,
+ * non-primary classes must be).
*/
protected JavaResourcePersistentType persistentType;
- public static final String PERSISTENT_TYPE_PROPERTY = "persistentTypeProperty";
-
- protected final JavaResourceModel javaResourceModel;
-
+
+
+ // ********** construction **********
+
public JpaCompilationUnitImpl(
IFile file,
JpaAnnotationProvider annotationProvider,
CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
AnnotationEditFormatter annotationEditFormatter,
JavaResourceModel javaResourceModel) {
- // The jpa compilation unit is the root of its sub-tree
- super(null);
+ super(null); // the JPA compilation unit is the root of its sub-tree
this.annotationProvider = annotationProvider;
this.modifySharedDocumentCommandExecutorProvider = modifySharedDocumentCommandExecutorProvider;
this.annotationEditFormatter = annotationEditFormatter;
this.javaResourceModel = javaResourceModel;
- this.compilationUnit = compilationUnitFrom(file);
- this.initialize(JDTTools.buildASTRoot(this.compilationUnit));
+ this.compilationUnit = JavaCore.createCompilationUnitFrom(file);
+ this.openCompilationUnit();
+ this.persistentType = this.buildJavaResourcePersistentType();
}
-
- protected ICompilationUnit compilationUnitFrom(IFile file) {
- ICompilationUnit cu = JavaCore.createCompilationUnitFrom(file);
+
+ protected void openCompilationUnit() {
try {
- cu.open(null);
- }
- catch (JavaModelException jme) {
+ this.compilationUnit.open(null);
+ } catch (JavaModelException ex) {
// do nothing - we just won't have a primary type in this case
}
- return cu;
}
-
+
+ protected JavaResourcePersistentType buildJavaResourcePersistentType() {
+ return this.buildJavaResourcePersistentType(this.buildASTRoot());
+ }
+
+ protected JavaResourcePersistentType buildJavaResourcePersistentType(CompilationUnit astRoot) {
+ TypeDeclaration td = this.getPrimaryType(astRoot);
+ return (td == null) ? null : this.buildJavaResourcePersistentType(astRoot, td);
+ }
+
public void initialize(CompilationUnit astRoot) {
- IType iType = this.compilationUnit.findPrimaryType();
- if (iType != null) {
- this.persistentType = buildJavaResourcePersistentType(iType, astRoot);
- }
+ // never called?
}
-
- // **************** overrides **********************************************
-
-
+
+
+ // ********** overrides **********
+
@Override
protected boolean requiresParent() {
return false;
@@ -114,18 +124,15 @@ public class JpaCompilationUnitImpl
return this.javaResourceModel;
}
-
- // *************************************************************************
-
+
+ // ********** JpaCompilationUnit implementation **********
+
public ICompilationUnit getCompilationUnit() {
return this.compilationUnit;
}
public JavaResourcePersistentType getJavaPersistentTypeResource(String fullyQualifiedTypeName) {
- if (getPersistentType() != null) {
- return getPersistentType().getJavaPersistentTypeResource(fullyQualifiedTypeName);
- }
- return null;
+ return (this.persistentType == null) ? null : this.persistentType.getJavaPersistentTypeResource(fullyQualifiedTypeName);
}
/**
@@ -136,79 +143,97 @@ public class JpaCompilationUnitImpl
return this.persistentType;
//TODO should i only be returning this if it returns true to isPersistable?
//that's how we handle nestedTypes on JavaPersistentTypeResource
-
-// if (this.persistentType.isPersistable()) {
-// return this.persistentType;
-// }
-// return null;
+ //return this.persistentType.isPersistable() ? this.persistentType : null;
}
- protected void setPersistentType(JavaResourcePersistentType newPersistentType) {
- JavaResourcePersistentType oldPersistentType = this.persistentType;
- this.persistentType = newPersistentType;
- firePropertyChanged(PERSISTENT_TYPE_PROPERTY, oldPersistentType, newPersistentType);
+ protected void setPersistentType(JavaResourcePersistentType persistentType) {
+ JavaResourcePersistentType old = this.persistentType;
+ this.persistentType = persistentType;
+ this.firePropertyChanged(PERSISTENT_TYPE_PROPERTY, old, persistentType);
}
-
- private JavaResourcePersistentType buildJavaResourcePersistentType(IType iType, CompilationUnit astRoot) {
- //TODO put this hook in to avoid the NPE that we get trying to initialize a persistentTypeResource
- //from an annotation type. Entered bug # to handle the bigger issue of when we need to
- //not build a persistent type(annotation types) and when we need to have validation instead(final types)
- try {
- if (iType.isAnnotation() || iType.isEnum()) {
- return null;
- }
- }
- catch (JavaModelException e) {
- throw new RuntimeException(e);
- }
- return
- JavaResourcePersistentTypeImpl.buildJavaResourcePersistentType(this,
- iType,
- getModifySharedDocumentCommandExecutorProvider(),
- getAnnotationEditFormatter(),
- astRoot);
- }
-
public void updateFromJava() {
- updateFromJava(JDTTools.buildASTRoot(getCompilationUnit()));
+ this.updateFromJava(this.buildASTRoot());
}
-
+
public void updateFromJava(CompilationUnit astRoot) {
- IType iType = this.compilationUnit.findPrimaryType();
- if (iType == null) {
- setPersistentType(null);
- }
- else {
- if (getPersistentType() == null) {
- setPersistentType(buildJavaResourcePersistentType(iType, astRoot));
- }
- else {
- getPersistentType().updateFromJava(astRoot);
+ TypeDeclaration td = this.getPrimaryType(astRoot);
+ if (td == null) {
+ this.setPersistentType(null);
+ } else {
+ if (this.persistentType == null) {
+ this.setPersistentType(this.buildJavaResourcePersistentType(astRoot, td));
+ } else {
+ this.persistentType.updateFromJava(astRoot);
}
}
}
-
-
+
public TextRange getTextRange(CompilationUnit astRoot) {
- return null;//this.selectionTextRange();
+ return null;
}
-// /**
-// * Return null for selection textRange. Entire java file will appear selected when
-// * switching files otherwise
-// */
-// public ITextRange selectionTextRange() {
-// return null;
-// }
-
public void resourceChanged() {
this.javaResourceModel.resourceChanged();
}
public void resolveTypes() {
- if (getPersistentType() != null) {
- getPersistentType().resolveTypes(JDTTools.buildASTRoot(getCompilationUnit()));
+ if (this.persistentType != null) {
+ this.persistentType.resolveTypes(this.buildASTRoot());
+ }
+ }
+
+
+ // ********** internal **********
+
+ protected CompilationUnit buildASTRoot() {
+ return JDTTools.buildASTRoot(this.compilationUnit);
+ }
+
+ // TODO use JPA factory
+ protected JavaResourcePersistentType buildJavaResourcePersistentType(CompilationUnit astRoot, TypeDeclaration typeDeclaration) {
+ return JavaResourcePersistentTypeImpl.newInstance(this, typeDeclaration, astRoot);
+ }
+
+ /**
+ * i.e. the type with the same name as the compilation unit;
+ * return the first class or interface (ignore annotations and enums) with
+ * the same name as the compilation unit (file);
+ * NB: this type could be in error if there is an annotation or enum
+ * with the same name preceding it in the compilation unit
+ */
+ protected TypeDeclaration getPrimaryType(CompilationUnit astRoot) {
+ String primaryTypeName = this.getPrimaryTypeName();
+ for (AbstractTypeDeclaration atd : types(astRoot)) {
+ if ((atd.getNodeType() == ASTNode.TYPE_DECLARATION)
+ && atd.getName().getFullyQualifiedName().equals(primaryTypeName)) {
+ return (TypeDeclaration) atd;
+ }
}
+ return null;
+ }
+
+ // minimize scope of suppressed warnings
+ @SuppressWarnings("unchecked")
+ protected static List<AbstractTypeDeclaration> types(CompilationUnit astRoot) {
+ return astRoot.types();
}
+
+ /**
+ * i.e. the name of the compilation unit
+ */
+ protected String getPrimaryTypeName() {
+ return removeJavaExtension(this.compilationUnit.getElementName());
+ }
+
+ protected static String removeJavaExtension(String fileName) {
+ int index = fileName.lastIndexOf(".java");
+ return (index == -1) ? fileName : fileName.substring(0, index);
+ }
+
+ @Override
+ public void toString(StringBuilder sb) {
+ sb.append(this.persistentType.getName());
+ }
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/synch/SynchronizeClassesJob.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/synch/SynchronizeClassesJob.java
index 2e7872b51d..fbf88c16b5 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/synch/SynchronizeClassesJob.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/synch/SynchronizeClassesJob.java
@@ -10,13 +10,14 @@
package org.eclipse.jpt.core.internal.synch;
import java.io.IOException;
+import java.util.Iterator;
+
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.core.IType;
import org.eclipse.jpt.core.JpaProject;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.context.persistence.MappingFileRef;
@@ -82,11 +83,11 @@ public class SynchronizeClassesJob extends WorkspaceJob
persistenceUnitResource.getClasses().clear();
- monitor.worked(25);
-
- for (IType type : CollectionTools.iterable(jpaProject.annotatedClasses())) {
- String fullyQualifiedTypeName = type.getFullyQualifiedName('.');
- if (!mappingFileContains(jpaProject, fullyQualifiedTypeName)) {
+ monitor.worked(25);
+
+ for (Iterator<String> stream = jpaProject.annotatedClassNames(); stream.hasNext(); ) {
+ String fullyQualifiedTypeName = stream.next();
+ if ( ! mappingFileContains(jpaProject, fullyQualifiedTypeName)) {
XmlJavaClassRef classRef = PersistenceFactory.eINSTANCE.createXmlJavaClassRef();
classRef.setJavaClass(fullyQualifiedTypeName);
persistenceUnitResource.getClasses().add(classRef);
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/ASTNodeSearchUtil.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/ASTNodeSearchUtil.java
deleted file mode 100644
index c1abe0ece0..0000000000
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/ASTNodeSearchUtil.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
- * 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:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jpt.core.internal.utility.jdt;
-
-import java.util.List;
-import org.eclipse.jdt.core.IField;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
-import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
-import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
-import org.eclipse.jdt.core.dom.BodyDeclaration;
-import org.eclipse.jdt.core.dom.ClassInstanceCreation;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
-import org.eclipse.jdt.core.dom.EnumDeclaration;
-import org.eclipse.jdt.core.dom.FieldDeclaration;
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jdt.core.dom.TypeDeclaration;
-import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
-
-//copied from org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil
-//deleted code to limit the number of classes I had to copy
-public class ASTNodeSearchUtil {
-
- private ASTNodeSearchUtil() {
- //no instance
- }
-
-
- public static MethodDeclaration getMethodDeclarationNode(IMethod iMethod, CompilationUnit cuNode) throws JavaModelException {
- return (MethodDeclaration)ASTNodes.getParent(getNameNode(iMethod, cuNode), MethodDeclaration.class);
- }
-
- public static ASTNode getParent(ASTNode node, Class<?> parentClass) {
- do {
- node= node.getParent();
- } while (node != null && !parentClass.isInstance(node));
- return node;
- }
-
-
- public static AnnotationTypeMemberDeclaration getAnnotationTypeMemberDeclarationNode(IMethod iMethod, CompilationUnit cuNode) throws JavaModelException {
- return (AnnotationTypeMemberDeclaration) ASTNodes.getParent(getNameNode(iMethod, cuNode), AnnotationTypeMemberDeclaration.class);
- }
-
- public static VariableDeclarationFragment getFieldDeclarationFragmentNode(IField iField, CompilationUnit cuNode) throws JavaModelException {
- ASTNode node= getNameNode(iField, cuNode);
- if (node instanceof VariableDeclarationFragment)
- return (VariableDeclarationFragment)node;
- return (VariableDeclarationFragment)ASTNodes.getParent(node, VariableDeclarationFragment.class);
- }
-
- public static FieldDeclaration getFieldDeclarationNode(IField iField, CompilationUnit cuNode) throws JavaModelException {
- return (FieldDeclaration) ASTNodes.getParent(getNameNode(iField, cuNode), FieldDeclaration.class);
- }
-
- public static EnumConstantDeclaration getEnumConstantDeclaration(IField iField, CompilationUnit cuNode) throws JavaModelException {
- return (EnumConstantDeclaration) ASTNodes.getParent(getNameNode(iField, cuNode), EnumConstantDeclaration.class);
- }
-
- public static EnumDeclaration getEnumDeclarationNode(IType iType, CompilationUnit cuNode) throws JavaModelException {
- return (EnumDeclaration) ASTNodes.getParent(getNameNode(iType, cuNode), EnumDeclaration.class);
- }
-
- public static AnnotationTypeDeclaration getAnnotationTypeDeclarationNode(IType iType, CompilationUnit cuNode) throws JavaModelException {
- return (AnnotationTypeDeclaration) ASTNodes.getParent(getNameNode(iType, cuNode), AnnotationTypeDeclaration.class);
- }
-
- public static BodyDeclaration getBodyDeclarationNode(IMember iMember, CompilationUnit cuNode) throws JavaModelException {
- return (BodyDeclaration) ASTNodes.getParent(getNameNode(iMember, cuNode), BodyDeclaration.class);
- }
-
- public static AbstractTypeDeclaration getAbstractTypeDeclarationNode(IType iType, CompilationUnit cuNode) throws JavaModelException {
- return (AbstractTypeDeclaration) ASTNodes.getParent(getNameNode(iType, cuNode), AbstractTypeDeclaration.class);
- }
-
- public static TypeDeclaration getTypeDeclarationNode(IType iType, CompilationUnit cuNode) throws JavaModelException {
- return (TypeDeclaration) ASTNodes.getParent(getNameNode(iType, cuNode), TypeDeclaration.class);
- }
-
- public static ClassInstanceCreation getClassInstanceCreationNode(IType iType, CompilationUnit cuNode) throws JavaModelException {
- return (ClassInstanceCreation) ASTNodes.getParent(getNameNode(iType, cuNode), ClassInstanceCreation.class);
- }
-
- @SuppressWarnings("unchecked")
- public static List<BodyDeclaration> getBodyDeclarationList(IType iType, CompilationUnit cuNode) throws JavaModelException {
- if (iType.isAnonymous())
- return getClassInstanceCreationNode(iType, cuNode).getAnonymousClassDeclaration().bodyDeclarations();
- return getAbstractTypeDeclarationNode(iType, cuNode).bodyDeclarations();
- }
-
- private static ASTNode getNameNode(IMember iMember, CompilationUnit cuNode) throws JavaModelException {
- return NodeFinder.perform(cuNode, iMember.getNameRange());
- }
-}
-
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/ASTNodes.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/ASTNodes.java
deleted file mode 100644
index 6a14ee33a8..0000000000
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/ASTNodes.java
+++ /dev/null
@@ -1,726 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
- * 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:
- * IBM Corporation - initial API and implementation
- * Dmitry Stalnov (dstalnov@fusionone.com) - contributed fix for
- * bug "inline method - doesn't handle implicit cast" (see
- * https://bugs.eclipse.org/bugs/show_bug.cgi?id=24941).
- * Dmitry Stalnov (dstalnov@fusionone.com) - contributed fix for
- * bug Encapsulate field can fail when two variables in one variable declaration (see
- * https://bugs.eclipse.org/bugs/show_bug.cgi?id=51540).
- *******************************************************************************/
-package org.eclipse.jpt.core.internal.utility.jdt;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.jdt.core.Flags;
-import org.eclipse.jdt.core.IField;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.ISourceReference;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.compiler.IProblem;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.ASTVisitor;
-import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
-import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
-import org.eclipse.jdt.core.dom.ArrayType;
-import org.eclipse.jdt.core.dom.Assignment;
-import org.eclipse.jdt.core.dom.BodyDeclaration;
-import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
-import org.eclipse.jdt.core.dom.ClassInstanceCreation;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.DoStatement;
-import org.eclipse.jdt.core.dom.EnhancedForStatement;
-import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
-import org.eclipse.jdt.core.dom.Expression;
-import org.eclipse.jdt.core.dom.FieldDeclaration;
-import org.eclipse.jdt.core.dom.ForStatement;
-import org.eclipse.jdt.core.dom.IBinding;
-import org.eclipse.jdt.core.dom.IExtendedModifier;
-import org.eclipse.jdt.core.dom.IMethodBinding;
-import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.IVariableBinding;
-import org.eclipse.jdt.core.dom.IfStatement;
-import org.eclipse.jdt.core.dom.InfixExpression;
-import org.eclipse.jdt.core.dom.Message;
-import org.eclipse.jdt.core.dom.MethodInvocation;
-import org.eclipse.jdt.core.dom.Modifier;
-import org.eclipse.jdt.core.dom.Name;
-import org.eclipse.jdt.core.dom.ParameterizedType;
-import org.eclipse.jdt.core.dom.PrimitiveType;
-import org.eclipse.jdt.core.dom.QualifiedName;
-import org.eclipse.jdt.core.dom.QualifiedType;
-import org.eclipse.jdt.core.dom.ReturnStatement;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.SimpleType;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
-import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
-import org.eclipse.jdt.core.dom.Type;
-import org.eclipse.jdt.core.dom.VariableDeclaration;
-import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
-import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
-import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
-import org.eclipse.jdt.core.dom.WhileStatement;
-
-
-//copied from org.eclipse.jdt.internal.corext.dom.ASTNodes
-//deleted code to limit the number of classes I had to copy
-public class ASTNodes {
-
- public static final int NODE_ONLY= 0;
- public static final int INCLUDE_FIRST_PARENT= 1;
- public static final int INCLUDE_ALL_PARENTS= 2;
-
- public static final int WARNING= 1 << 0;
- public static final int ERROR= 1 << 1;
- public static final int PROBLEMS= WARNING | ERROR;
-
- private static final Message[] EMPTY_MESSAGES= new Message[0];
- private static final IProblem[] EMPTY_PROBLEMS= new IProblem[0];
-
- private static final int CLEAR_VISIBILITY= ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE);
-
-
- private ASTNodes() {
- // no instance;
- }
-
- /**
- * Returns the list that contains the given ASTNode. If the node
- * isn't part of any list, <code>null</code> is returned.
- *
- * @param node the node in question
- * @return the list that contains the node or <code>null</code>
- */
- @SuppressWarnings("unchecked")
- public static List<ASTNode> getContainingList(ASTNode node) {
- StructuralPropertyDescriptor locationInParent= node.getLocationInParent();
- if (locationInParent != null && locationInParent.isChildListProperty()) {
- return (List<ASTNode>) node.getParent().getStructuralProperty(locationInParent);
- }
- return null;
- }
-
- /**
- * Returns a list of the direct children of a node. The siblings are ordered by start offset.
- * @param node the node to get the children for
- * @return the children
- */
- public static List<ASTNode> getChildren(ASTNode node) {
- ChildrenCollector visitor= new ChildrenCollector();
- node.accept(visitor);
- return visitor.result;
- }
-
- private static class ChildrenCollector extends GenericVisitor {
- public List<ASTNode> result;
-
- public ChildrenCollector() {
- super(true);
- result= null;
- }
- @Override
- protected boolean visitNode(ASTNode node) {
- if (result == null) { // first visitNode: on the node's parent: do nothing, return true
- result= new ArrayList<ASTNode>();
- return true;
- }
- result.add(node);
- return false;
- }
- }
-
- /**
- * Returns true if this is an existing node, i.e. it was created as part of
- * a parsing process of a source code file. Returns false if this is a newly
- * created node which has not yet been given a source position.
- *
- * @param node the node to be tested.
- * @return true if this is an existing node, false if not.
- */
- public static boolean isExistingNode(ASTNode node) {
- return node.getStartPosition() != -1;
- }
-
- /**
- * Returns the element type. This is a convenience method that returns its
- * argument if it is a simple type and the element type if the parameter is an array type.
- * @param type The type to get the element type from.
- * @return The element type of the type or the type itself.
- */
- public static Type getElementType(Type type) {
- if (! type.isArrayType())
- return type;
- return ((ArrayType)type).getElementType();
- }
-
- public static ASTNode findDeclaration(IBinding binding, ASTNode root) {
- root= root.getRoot();
- if (root instanceof CompilationUnit) {
- return ((CompilationUnit)root).findDeclaringNode(binding);
- }
- return null;
- }
-
- public static VariableDeclaration findVariableDeclaration(IVariableBinding binding, ASTNode root) {
- if (binding.isField())
- return null;
- ASTNode result= findDeclaration(binding, root);
- if (result instanceof VariableDeclaration)
- return (VariableDeclaration)result;
-
- return null;
- }
-
- /**
- * Returns the type node for the given declaration.
- * @param declaration the declaration
- * @return the type node
- */
- public static Type getType(VariableDeclaration declaration) {
- if (declaration instanceof SingleVariableDeclaration) {
- return ((SingleVariableDeclaration)declaration).getType();
- } else if (declaration instanceof VariableDeclarationFragment) {
- ASTNode parent= ((VariableDeclarationFragment)declaration).getParent();
- if (parent instanceof VariableDeclarationExpression)
- return ((VariableDeclarationExpression)parent).getType();
- else if (parent instanceof VariableDeclarationStatement)
- return ((VariableDeclarationStatement)parent).getType();
- else if (parent instanceof FieldDeclaration)
- return ((FieldDeclaration)parent).getType();
- }
- Assert.isTrue(false, "Unknown VariableDeclaration"); //$NON-NLS-1$
- return null;
- }
-
- public static int getDimensions(VariableDeclaration declaration) {
- int dim= declaration.getExtraDimensions();
- Type type= getType(declaration);
- if (type instanceof ArrayType) {
- dim += ((ArrayType) type).getDimensions();
- }
- return dim;
- }
-
- @SuppressWarnings("unchecked")
- public static List<IExtendedModifier> getModifiers(VariableDeclaration declaration) {
- Assert.isNotNull(declaration);
- if (declaration instanceof SingleVariableDeclaration) {
- return ((SingleVariableDeclaration)declaration).modifiers();
- } else if (declaration instanceof VariableDeclarationFragment) {
- ASTNode parent= declaration.getParent();
- if (parent instanceof VariableDeclarationExpression)
- return ((VariableDeclarationExpression)parent).modifiers();
- else if (parent instanceof VariableDeclarationStatement)
- return ((VariableDeclarationStatement)parent).modifiers();
- }
- return new ArrayList<IExtendedModifier>(0);
- }
-
- public static boolean isSingleDeclaration(VariableDeclaration declaration) {
- Assert.isNotNull(declaration);
- if (declaration instanceof SingleVariableDeclaration) {
- return true;
- } else if (declaration instanceof VariableDeclarationFragment) {
- ASTNode parent= declaration.getParent();
- if (parent instanceof VariableDeclarationExpression)
- return ((VariableDeclarationExpression)parent).fragments().size() == 1;
- else if (parent instanceof VariableDeclarationStatement)
- return ((VariableDeclarationStatement)parent).fragments().size() == 1;
- }
- return false;
- }
-
- public static boolean isLiteral(Expression expression) {
- int type= expression.getNodeType();
- return type == ASTNode.BOOLEAN_LITERAL || type == ASTNode.CHARACTER_LITERAL || type == ASTNode.NULL_LITERAL ||
- type == ASTNode.NUMBER_LITERAL || type == ASTNode.STRING_LITERAL || type == ASTNode.TYPE_LITERAL;
- }
-
- public static boolean isLabel(SimpleName name) {
- int parentType= name.getParent().getNodeType();
- return parentType == ASTNode.LABELED_STATEMENT ||
- parentType == ASTNode.BREAK_STATEMENT || parentType != ASTNode.CONTINUE_STATEMENT;
- }
-
- public static boolean isStatic(BodyDeclaration declaration) {
- return Modifier.isStatic(declaration.getModifiers());
- }
-
- @SuppressWarnings("unchecked")
- public static List<BodyDeclaration> getBodyDeclarations(ASTNode node) {
- if (node instanceof AbstractTypeDeclaration) {
- return ((AbstractTypeDeclaration)node).bodyDeclarations();
- } else if (node instanceof AnonymousClassDeclaration) {
- return ((AnonymousClassDeclaration)node).bodyDeclarations();
- }
- // should not happen.
- Assert.isTrue(false);
- return null;
- }
-
- public static ChildListPropertyDescriptor getBodyDeclarationsProperty(ASTNode node) {
- if (node instanceof AbstractTypeDeclaration) {
- return ((AbstractTypeDeclaration)node).getBodyDeclarationsProperty();
- } else if (node instanceof AnonymousClassDeclaration) {
- return AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;
- }
- // should not happen.
- Assert.isTrue(false);
- return null;
- }
-
- public static String getTypeName(Type type) {
- final StringBuffer buffer= new StringBuffer();
- ASTVisitor visitor= new ASTVisitor() {
- @Override
- public boolean visit(PrimitiveType node) {
- buffer.append(node.getPrimitiveTypeCode().toString());
- return false;
- }
- @Override
- public boolean visit(SimpleName node) {
- buffer.append(node.getIdentifier());
- return false;
- }
- @Override
- public boolean visit(QualifiedName node) {
- buffer.append(node.getName().getIdentifier());
- return false;
- }
- @Override
- public void endVisit(ArrayType node) {
- buffer.append("[]"); //$NON-NLS-1$
- }
- };
- type.accept(visitor);
- return buffer.toString();
- }
-
- public static InfixExpression.Operator convertToInfixOperator(Assignment.Operator operator) {
- if (operator.equals(Assignment.Operator.PLUS_ASSIGN))
- return InfixExpression.Operator.PLUS;
-
- if (operator.equals(Assignment.Operator.MINUS_ASSIGN))
- return InfixExpression.Operator.MINUS;
-
- if (operator.equals(Assignment.Operator.TIMES_ASSIGN))
- return InfixExpression.Operator.TIMES;
-
- if (operator.equals(Assignment.Operator.DIVIDE_ASSIGN))
- return InfixExpression.Operator.DIVIDE;
-
- if (operator.equals(Assignment.Operator.BIT_AND_ASSIGN))
- return InfixExpression.Operator.AND;
-
- if (operator.equals(Assignment.Operator.BIT_OR_ASSIGN))
- return InfixExpression.Operator.OR;
-
- if (operator.equals(Assignment.Operator.BIT_XOR_ASSIGN))
- return InfixExpression.Operator.XOR;
-
- if (operator.equals(Assignment.Operator.REMAINDER_ASSIGN))
- return InfixExpression.Operator.REMAINDER;
-
- if (operator.equals(Assignment.Operator.LEFT_SHIFT_ASSIGN))
- return InfixExpression.Operator.LEFT_SHIFT;
-
- if (operator.equals(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN))
- return InfixExpression.Operator.RIGHT_SHIFT_SIGNED;
-
- if (operator.equals(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN))
- return InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED;
-
- Assert.isTrue(false, "Cannot convert assignment operator"); //$NON-NLS-1$
- return null;
- }
-
- /**
- * Returns true if a node at a given location is a body of a control statement. Such body nodes are
- * interesting as when replacing them, it has to be evaluates if a Block is needed instead.
- * E.g. <code> if (x) do(); -> if (x) { do1(); do2() } </code>
- *
- * @param locationInParent Location of the body node
- * @return Returns true if the location is a body node location of a control statement.
- */
- public static boolean isControlStatementBody(StructuralPropertyDescriptor locationInParent) {
- return locationInParent == IfStatement.THEN_STATEMENT_PROPERTY
- || locationInParent == IfStatement.ELSE_STATEMENT_PROPERTY
- || locationInParent == ForStatement.BODY_PROPERTY
- || locationInParent == EnhancedForStatement.BODY_PROPERTY
- || locationInParent == WhileStatement.BODY_PROPERTY
- || locationInParent == DoStatement.BODY_PROPERTY;
- }
-
- public static boolean needsParentheses(Expression expression) {
- int type= expression.getNodeType();
- return type == ASTNode.INFIX_EXPRESSION || type == ASTNode.CONDITIONAL_EXPRESSION ||
- type == ASTNode.PREFIX_EXPRESSION || type == ASTNode.POSTFIX_EXPRESSION ||
- type == ASTNode.CAST_EXPRESSION || type == ASTNode.INSTANCEOF_EXPRESSION;
- }
-
-
- public static boolean substituteMustBeParenthesized(Expression substitute, Expression location) {
- if (!needsParentheses(substitute))
- return false;
-
- ASTNode parent= location.getParent();
- if (parent instanceof VariableDeclarationFragment){
- VariableDeclarationFragment vdf= (VariableDeclarationFragment)parent;
- if (vdf.getInitializer().equals(location))
- return false;
- } else if (parent instanceof MethodInvocation){
- MethodInvocation mi= (MethodInvocation)parent;
- if (mi.arguments().contains(location))
- return false;
- } else if (parent instanceof ReturnStatement)
- return false;
-
- return true;
- }
-
- public static ASTNode getParent(ASTNode node, Class<? extends ASTNode> parentClass) {
- do {
- node= node.getParent();
- } while (node != null && !parentClass.isInstance(node));
- return node;
- }
-
- public static ASTNode getParent(ASTNode node, int nodeType) {
- do {
- node= node.getParent();
- } while (node != null && node.getNodeType() != nodeType);
- return node;
- }
-
- public static ASTNode findParent(ASTNode node, StructuralPropertyDescriptor[][] pathes) {
- for (int p= 0; p < pathes.length; p++) {
- StructuralPropertyDescriptor[] path= pathes[p];
- ASTNode current= node;
- int d= path.length - 1;
- for (; d >= 0 && current != null; d--) {
- StructuralPropertyDescriptor descriptor= path[d];
- if (!descriptor.equals(current.getLocationInParent()))
- break;
- current= current.getParent();
- }
- if (d < 0)
- return current;
- }
- return null;
- }
-
- public static ASTNode getNormalizedNode(ASTNode node) {
- ASTNode current= node;
- // normalize name
- if (QualifiedName.NAME_PROPERTY.equals(current.getLocationInParent())) {
- current= current.getParent();
- }
- // normalize type
- if (QualifiedType.NAME_PROPERTY.equals(current.getLocationInParent()) ||
- SimpleType.NAME_PROPERTY.equals(current.getLocationInParent())) {
- current= current.getParent();
- }
- // normalize parameterized types
- if (ParameterizedType.TYPE_PROPERTY.equals(current.getLocationInParent())) {
- current= current.getParent();
- }
- return current;
- }
-
- public static boolean isParent(ASTNode node, ASTNode parent) {
- Assert.isNotNull(parent);
- do {
- node= node.getParent();
- if (node == parent)
- return true;
- } while (node != null);
- return false;
- }
-
- public static int getExclusiveEnd(ASTNode node){
- return node.getStartPosition() + node.getLength();
- }
-
- public static int getInclusiveEnd(ASTNode node){
- return node.getStartPosition() + node.getLength() - 1;
- }
-
- public static IMethodBinding getMethodBinding(Name node) {
- IBinding binding= node.resolveBinding();
- if (binding instanceof IMethodBinding)
- return (IMethodBinding)binding;
- return null;
- }
-
- public static IVariableBinding getVariableBinding(Name node) {
- IBinding binding= node.resolveBinding();
- if (binding instanceof IVariableBinding)
- return (IVariableBinding)binding;
- return null;
- }
-
- public static IVariableBinding getLocalVariableBinding(Name node) {
- IVariableBinding result= getVariableBinding(node);
- if (result == null || result.isField())
- return null;
-
- return result;
- }
-
- public static IVariableBinding getFieldBinding(Name node) {
- IVariableBinding result= getVariableBinding(node);
- if (result == null || !result.isField())
- return null;
-
- return result;
- }
-
- public static ITypeBinding getTypeBinding(Name node) {
- IBinding binding= node.resolveBinding();
- if (binding instanceof ITypeBinding)
- return (ITypeBinding)binding;
- return null;
- }
-
- /**
- * Returns the receiver's type binding of the given method invocation.
- *
- * @param invocation method invocation to resolve type of
- * @return the type binding of the receiver
- */
- public static ITypeBinding getReceiverTypeBinding(MethodInvocation invocation) {
- ITypeBinding result= null;
- Expression exp= invocation.getExpression();
- if(exp != null) {
- return exp.resolveTypeBinding();
- }
- AbstractTypeDeclaration type= (AbstractTypeDeclaration)getParent(invocation, AbstractTypeDeclaration.class);
- if (type != null)
- return type.resolveBinding();
- return result;
- }
-
- public static ITypeBinding getEnclosingType(ASTNode node) {
- while(node != null) {
- if (node instanceof AbstractTypeDeclaration) {
- return ((AbstractTypeDeclaration)node).resolveBinding();
- } else if (node instanceof AnonymousClassDeclaration) {
- return ((AnonymousClassDeclaration)node).resolveBinding();
- }
- node= node.getParent();
- }
- return null;
- }
-
- public static IProblem[] getProblems(ASTNode node, int scope, int severity) {
- ASTNode root= node.getRoot();
- if (!(root instanceof CompilationUnit))
- return EMPTY_PROBLEMS;
- IProblem[] problems= ((CompilationUnit)root).getProblems();
- if (root == node)
- return problems;
- final int iterations= computeIterations(scope);
- List<IProblem> result= new ArrayList<IProblem>(5);
- for (int i= 0; i < problems.length; i++) {
- IProblem problem= problems[i];
- boolean consider= false;
- if ((severity & PROBLEMS) == PROBLEMS)
- consider= true;
- else if ((severity & WARNING) != 0)
- consider= problem.isWarning();
- else if ((severity & ERROR) != 0)
- consider= problem.isError();
- if (consider) {
- ASTNode temp= node;
- int count= iterations;
- do {
- int nodeOffset= temp.getStartPosition();
- int problemOffset= problem.getSourceStart();
- if (nodeOffset <= problemOffset && problemOffset < nodeOffset + temp.getLength()) {
- result.add(problem);
- count= 0;
- } else {
- count--;
- }
- } while ((temp= temp.getParent()) != null && count > 0);
- }
- }
- return result.toArray(new IProblem[result.size()]);
- }
-
- public static Message[] getMessages(ASTNode node, int flags) {
- ASTNode root= node.getRoot();
- if (!(root instanceof CompilationUnit))
- return EMPTY_MESSAGES;
- Message[] messages= ((CompilationUnit)root).getMessages();
- if (root == node)
- return messages;
- final int iterations= computeIterations(flags);
- List<Message> result= new ArrayList<Message>(5);
- for (int i= 0; i < messages.length; i++) {
- Message message= messages[i];
- ASTNode temp= node;
- int count= iterations;
- do {
- int nodeOffset= temp.getStartPosition();
- int messageOffset= message.getStartPosition();
- if (nodeOffset <= messageOffset && messageOffset < nodeOffset + temp.getLength()) {
- result.add(message);
- count= 0;
- } else {
- count--;
- }
- } while ((temp= temp.getParent()) != null && count > 0);
- }
- return result.toArray(new Message[result.size()]);
- }
-
- private static int computeIterations(int flags) {
- switch (flags) {
- case NODE_ONLY:
- return 1;
- case INCLUDE_ALL_PARENTS:
- return Integer.MAX_VALUE;
- case INCLUDE_FIRST_PARENT:
- return 2;
- default:
- return 1;
- }
- }
-
- public static SimpleName getLeftMostSimpleName(Name name) {
- if (name instanceof SimpleName) {
- return (SimpleName)name;
- }
- final SimpleName[] result= new SimpleName[1];
- ASTVisitor visitor= new ASTVisitor() {
- @Override
- public boolean visit(QualifiedName qualifiedName) {
- Name left= qualifiedName.getQualifier();
- if (left instanceof SimpleName)
- result[0]= (SimpleName)left;
- else
- left.accept(this);
- return false;
- }
- };
- name.accept(visitor);
- return result[0];
- }
-
- public static SimpleType getLeftMostSimpleType(QualifiedType type) {
- final SimpleType[] result= new SimpleType[1];
- ASTVisitor visitor= new ASTVisitor() {
- @Override
- public boolean visit(QualifiedType qualifiedType) {
- Type left= qualifiedType.getQualifier();
- if (left instanceof SimpleType)
- result[0]= (SimpleType)left;
- else
- left.accept(this);
- return false;
- }
- };
- type.accept(visitor);
- return result[0];
- }
-
- public static Name getTopMostName(Name name) {
- Name result= name;
- while(result.getParent() instanceof Name) {
- result= (Name)result.getParent();
- }
- return result;
- }
-
- public static Type getTopMostType(Type type) {
- Type result= type;
- while(result.getParent() instanceof Type) {
- result= (Type)result.getParent();
- }
- return result;
- }
-
- public static int changeVisibility(int modifiers, int visibility) {
- return (modifiers & CLEAR_VISIBILITY) | visibility;
- }
-
- /**
- * Adds flags to the given node and all its descendants.
- * @param root The root node
- * @param flags The flags to set
- */
- public static void setFlagsToAST(ASTNode root, final int flags) {
- root.accept(new GenericVisitor(true) {
- @Override
- protected boolean visitNode(ASTNode node) {
- node.setFlags(node.getFlags() | flags);
- return true;
- }
- });
- }
-
- public static String getQualifier(Name name) {
- if (name.isQualifiedName()) {
- return ((QualifiedName) name).getQualifier().getFullyQualifiedName();
- }
- return ""; //$NON-NLS-1$
- }
-
- public static String getSimpleNameIdentifier(Name name) {
- if (name.isQualifiedName()) {
- return ((QualifiedName) name).getName().getIdentifier();
- }
- return ((SimpleName) name).getIdentifier();
- }
-
- public static boolean isDeclaration(Name name) {
- if (name.isQualifiedName()) {
- return ((QualifiedName) name).getName().isDeclaration();
- }
- return ((SimpleName) name).isDeclaration();
- }
-
- public static Modifier findModifierNode(int flag, List<?> modifiers) {
- for (int i= 0; i < modifiers.size(); i++) {
- Object curr= modifiers.get(i);
- if (curr instanceof Modifier && ((Modifier) curr).getKeyword().toFlagValue() == flag) {
- return (Modifier) curr;
- }
- }
- return null;
- }
-
- public static ITypeBinding getTypeBinding(CompilationUnit root, IType type) throws JavaModelException {
- if (type.isAnonymous()) {
- final IJavaElement parent= type.getParent();
- if (parent instanceof IField && Flags.isEnum(((IMember) parent).getFlags())) {
- final EnumConstantDeclaration constant= (EnumConstantDeclaration) NodeFinder.perform(root, ((ISourceReference) parent).getSourceRange());
- if (constant != null) {
- final AnonymousClassDeclaration declaration= constant.getAnonymousClassDeclaration();
- if (declaration != null)
- return declaration.resolveBinding();
- }
- } else {
- final ClassInstanceCreation creation= (ClassInstanceCreation) getParent(NodeFinder.perform(root, type.getNameRange()), ClassInstanceCreation.class);
- if (creation != null)
- return creation.resolveTypeBinding();
- }
- } else {
- final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) getParent(NodeFinder.perform(root, type.getNameRange()), AbstractTypeDeclaration.class);
- if (declaration != null)
- return declaration.resolveBinding();
- }
- return null;
- }
-}
-
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTAttribute.java
index 8e4059748a..0de59055c8 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTAttribute.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTAttribute.java
@@ -9,29 +9,47 @@
******************************************************************************/
package org.eclipse.jpt.core.internal.utility.jdt;
-import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jpt.core.utility.jdt.AnnotationEditFormatter;
import org.eclipse.jpt.core.utility.jdt.Attribute;
+import org.eclipse.jpt.core.utility.jdt.Type;
import org.eclipse.jpt.utility.CommandExecutorProvider;
/**
- * Combine behavior common to FieldAttribute and MethodAttribute.
+ * Combine behavior common to JDTFieldAttribute and JDTMethodAttribute.
+ * Not so sure this is useful....
*/
public abstract class JDTAttribute
extends JDTMember
implements Attribute
{
- JDTAttribute(IMember jdtMember, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
- super(jdtMember, modifySharedDocumentCommandExecutorProvider);
+ // ********** constructors **********
+
+ protected JDTAttribute(
+ Type declaringType,
+ String name,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
+ super(declaringType, name, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider);
}
-
- JDTAttribute(IMember jdtMember, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider, AnnotationEditFormatter annotationEditFormatter) {
- super(jdtMember, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
+
+ protected JDTAttribute(
+ Type declaringType,
+ String name,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
+ AnnotationEditFormatter annotationEditFormatter) {
+ super(declaringType, name, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
}
+
+ // ********** Member/Attribute implementation **********
+
public boolean isField() {
return false;
}
@@ -40,11 +58,13 @@ public abstract class JDTAttribute
return false;
}
- /**
- * this will throw a NPE for a top-level type
- */
- TypeDeclaration declaringTypeDeclaration(CompilationUnit astRoot) {
- //assume no enums or annotation types since they have no field or method declarations
- return (TypeDeclaration) this.declaringType().getBodyDeclaration(astRoot);
+
+ // ********** internal **********
+
+ protected TypeDeclaration getDeclaringTypeDeclaration(CompilationUnit astRoot) {
+ // assume the declaring type is not an enum or annotation
+ // since they do not have field or method declarations
+ return this.getDeclaringType().getBodyDeclaration(astRoot);
}
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTFieldAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTFieldAttribute.java
index 262775d06c..bdcbec67db 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTFieldAttribute.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTFieldAttribute.java
@@ -10,7 +10,9 @@
package org.eclipse.jpt.core.internal.utility.jdt;
import java.util.List;
-import org.eclipse.jdt.core.IField;
+
+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;
@@ -19,10 +21,11 @@ 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.
+ * Adapt and extend a JDT field.
* Attribute based on a Java field, e.g.
* private int foo;
*/
@@ -31,75 +34,148 @@ public class JDTFieldAttribute
implements FieldAttribute
{
- public JDTFieldAttribute(IField field, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
- super(field, modifySharedDocumentCommandExecutorProvider);
+ // ********** constructors **********
+
+ public JDTFieldAttribute(
+ Type declaringType,
+ String name,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
+ this(declaringType, name, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, DefaultAnnotationEditFormatter.instance());
}
- public JDTFieldAttribute(IField field, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider, AnnotationEditFormatter annotationEditFormatter) {
- super(field, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
+ public JDTFieldAttribute(
+ Type declaringType,
+ String name,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
+ AnnotationEditFormatter annotationEditFormatter) {
+ super(declaringType, name, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
}
- @Override
- public IField getJdtMember() {
- return (IField) super.getJdtMember();
+ /**
+ * constructor for testing
+ */
+ public JDTFieldAttribute(Type declaringType, String name, int occurrence, ICompilationUnit compilationUnit) {
+ this(declaringType, name, occurrence, compilationUnit, CommandExecutorProvider.Default.instance(), DefaultAnnotationEditFormatter.instance());
}
- // ********** Member implementation **********
+ // ********** Member/Attribute/FieldAttribute implementation **********
- public FieldDeclaration getBodyDeclaration(CompilationUnit astRoot) {
- String fieldName = this.getName();
- for (FieldDeclaration fieldDeclaration : this.declaringTypeDeclaration(astRoot).getFields()) {
- // handle multiple fields declared in a single statement:
- // private int foo, bar;
- for (VariableDeclarationFragment fragment : this.fragments(fieldDeclaration)) {
- if (fragment.getName().getFullyQualifiedName().equals(fieldName)) {
- return fieldDeclaration;
- }
- }
- }
- return null;
+ public IVariableBinding getBinding(CompilationUnit astRoot) {
+ return this.getFragment(astRoot).resolveBinding();
}
- private VariableDeclarationFragment getFragment(CompilationUnit astRoot) {
- FieldDeclaration fieldDeclaration = getBodyDeclaration(astRoot);
- for (VariableDeclarationFragment fragment : this.fragments(fieldDeclaration)) {
- if (fragment.getName().getFullyQualifiedName().equals(getName())) {
- return fragment;
- }
- }
- //TODO could this ever happen, should I throw an exception instead?
- return null;
- }
-
- public IVariableBinding getBinding(CompilationUnit astRoot) {
- return getFragment(astRoot).resolveBinding();
+ public FieldDeclaration getBodyDeclaration(CompilationUnit astRoot) {
+ return this.getSelectedDeclaration(astRoot, FIELD_DECLARATION_SELECTOR);
}
-
+
public TextRange getNameTextRange(CompilationUnit astRoot) {
- return new ASTNodeTextRange(getFragment(astRoot).getName());
+ return new ASTNodeTextRange(this.getFragment(astRoot).getName());
}
- // ********** Attribute implementation **********
+ public String getAttributeName() {
+ return this.getName_();
+ }
+
+ public ITypeBinding getTypeBinding(CompilationUnit astRoot) {
+ return this.getBodyDeclaration(astRoot).getType().resolveBinding();
+ }
@Override
public boolean isField() {
return true;
}
- public String getAttributeName() {
- return this.getName();
+ public boolean isPersistable(CompilationUnit astRoot) {
+ IVariableBinding binding = this.getBinding(astRoot);
+ return (binding == null) ? false : JPTTools.fieldIsPersistable(binding);
}
- public ITypeBinding getTypeBinding(CompilationUnit astRoot) {
- return getBodyDeclaration(astRoot).getType().resolveBinding();
+
+ // ********** internal **********
+
+ protected VariableDeclarationFragment getFragment(CompilationUnit astRoot) {
+ return this.getSelectedDeclaration(astRoot, VARIABLE_DECLARATION_FRAGMENT_SELECTOR);
}
- // ********** miscellaneous **********
+ /**
+ * 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 List<VariableDeclarationFragment> fragments(FieldDeclaration fd) {
+ 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";
+ }
+ @Override
+ public String toString() {
+ return "FIELD_DECLARATION_SELECTOR";
+ }
+ };
+
+ 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";
+ }
+ @Override
+ public String toString() {
+ return "VARIABLE_DECLARATION_FRAGMENT_SELECTOR";
+ }
+ };
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMember.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMember.java
index 29816fab7b..fec82d670a 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMember.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMember.java
@@ -13,8 +13,6 @@ import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jface.text.BadLocationException;
@@ -37,80 +35,100 @@ import org.eclipse.text.edits.TextEdit;
public abstract class JDTMember
implements Member
{
+ /** this will be null for the primary type */
+ private final Type declaringType;
- private final IMember jdtMember;
+ /** the member's name (duh) */
+ private final String name;
- /** this will be null for a top-level type */
- private final Type declaringType;
+ /**
+ * members can occur more than once in non-compiling source;
+ * count starts at 1; the primary type will have occurrence 1
+ */
+ private final int occurrence;
+ /**
+ * the compilation unit (file) containing the member;
+ * used for building an AST when we modify the member
+ */
+ private final ICompilationUnit compilationUnit;
+
+ /**
+ * this allows clients to provide a way to modify the compilation unit
+ * (file) when it is open in an editor and should be modified on the UI
+ * thread
+ */
private final CommandExecutorProvider modifySharedDocumentCommandExecutorProvider;
+ /** this will format the member's annotations a bit */
private final AnnotationEditFormatter annotationEditFormatter;
- // ********** constructor **********
-
- JDTMember(IMember jdtMember, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
- this(jdtMember, modifySharedDocumentCommandExecutorProvider, DefaultAnnotationEditFormatter.instance());
- }
+
+ // ********** constructors **********
- JDTMember(IMember jdtMember, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider, AnnotationEditFormatter annotationEditFormatter) {
+ protected JDTMember(
+ Type declaringType,
+ String name,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
+ this(declaringType, name, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, DefaultAnnotationEditFormatter.instance());
+ }
+
+ protected JDTMember(
+ Type declaringType,
+ String name,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
+ AnnotationEditFormatter annotationEditFormatter) {
super();
- this.jdtMember = jdtMember;
- IType jdtDeclaringType = jdtMember.getDeclaringType();
- this.declaringType = (jdtDeclaringType == null) ? null : new JDTType(jdtDeclaringType, modifySharedDocumentCommandExecutorProvider);
+ this.declaringType = declaringType;
+ this.name = name;
+ this.occurrence = occurrence;
+ this.compilationUnit = compilationUnit;
this.modifySharedDocumentCommandExecutorProvider = modifySharedDocumentCommandExecutorProvider;
this.annotationEditFormatter = annotationEditFormatter;
}
- // ********** accessors **********
+ // ********** Member implementation **********
- protected IMember getJdtMember() {
- return this.jdtMember;
+ public ModifiedDeclaration getModifiedDeclaration(CompilationUnit astRoot) {
+ return new JDTModifiedDeclaration(this.getBodyDeclaration(astRoot));
}
- public boolean wraps(IMember member) {
- return this.jdtMember.exists()
- && this.jdtMember.equals(member);
+ public ModifiedDeclaration getModifiedDeclaration() {
+ return this.getModifiedDeclaration(this.buildASTRoot());
}
- /**
- * this will return null for a top-level type
- */
- protected Type declaringType() {
- return this.declaringType;
+ public boolean matches(String memberName, int occur) {
+ return memberName.equals(this.name) && (occur == this.occurrence);
}
+ @Override
+ public String toString() {
+ return StringTools.buildToStringFor(this, this.name);
+ }
- // ********** miscellaneous **********
- protected ICompilationUnit getCompilationUnit() {
- return this.jdtMember.getCompilationUnit();
+ // ********** internal **********
+
+ protected String getName_() {
+ return this.name;
}
- public String getName() {
- return this.jdtMember.getElementName();
+ protected int getOccurrence() {
+ return this.occurrence;
}
/**
- * note: this creates a *new* AST
+ * this will return null for a top-level type
*/
- public CompilationUnit getAstRoot() {
- return JDTTools.buildASTRoot(this.jdtMember);
- }
-
- public ModifiedDeclaration getModifiedDeclaration() {
- return this.getModifiedDeclaration(this.getAstRoot());
- }
-
- public ModifiedDeclaration getModifiedDeclaration(CompilationUnit astRoot) {
- return new JDTModifiedDeclaration(this.getBodyDeclaration(astRoot));
+ protected Type getDeclaringType() {
+ return this.declaringType;
}
- @Override
- public String toString() {
- return StringTools.buildToStringFor(this, this.getName());
- }
// ********** editing **********
@@ -138,25 +156,24 @@ public abstract class JDTMember
* - when editing via a plain text editor, make a working copy or else things are screwed
* up the second time you edit through the XmlPersistence XmlProperties View
*/
- private void edit_(Editor editor) throws JavaModelException, BadLocationException {
- ICompilationUnit compilationUnit = this.getCompilationUnit();
- if ( ! compilationUnit.isWorkingCopy()) {
- compilationUnit.becomeWorkingCopy(null);
+ protected void edit_(Editor editor) throws JavaModelException, BadLocationException {
+ if ( ! this.compilationUnit.isWorkingCopy()) {
+ this.compilationUnit.becomeWorkingCopy(null);
}
- ITextFileBuffer buffer = FileBuffers.getTextFileBufferManager().getTextFileBuffer(compilationUnit.getResource().getFullPath(), LocationKind.NORMALIZE);
+ ITextFileBuffer buffer = FileBuffers.getTextFileBufferManager().getTextFileBuffer(this.compilationUnit.getResource().getFullPath(), LocationKind.NORMALIZE);
boolean sharedDocument = (buffer != null); // documents are typically shared when they are already open in an editor
IDocument doc = sharedDocument ?
buffer.getDocument()
:
- new Document(compilationUnit.getBuffer().getContents());
+ new Document(this.compilationUnit.getBuffer().getContents());
- CompilationUnit astRoot = this.getAstRoot();
+ CompilationUnit astRoot = this.buildASTRoot();
astRoot.recordModifications();
editor.edit(this.getModifiedDeclaration(astRoot));
- TextEdit edits = astRoot.rewrite(doc, compilationUnit.getJavaProject().getOptions(true));
+ TextEdit edits = astRoot.rewrite(doc, this.compilationUnit.getJavaProject().getOptions(true));
if (sharedDocument) {
this.getModifySharedDocumentCommandExecutor().execute(new ModifySharedDocumentCommand(edits, doc));
} else {
@@ -164,9 +181,9 @@ public abstract class JDTMember
}
if ( ! sharedDocument) {
- compilationUnit.getBuffer().setContents(doc.get());
- compilationUnit.commitWorkingCopy(true, null); // true="force"
- compilationUnit.discardWorkingCopy();
+ this.compilationUnit.getBuffer().setContents(doc.get());
+ this.compilationUnit.commitWorkingCopy(true, null); // true="force"
+ this.compilationUnit.discardWorkingCopy();
}
}
@@ -174,16 +191,16 @@ public abstract class JDTMember
* apply the specified edits to the specified document,
* reformatting the document if necessary
*/
- void applyEdits(TextEdit edits, IDocument doc) throws MalformedTreeException, BadLocationException {
+ protected void applyEdits(TextEdit edits, IDocument doc) throws MalformedTreeException, BadLocationException {
edits.apply(doc, TextEdit.UPDATE_REGIONS);
- this.getAnnotationEditFormatter().format(doc, edits);
+ this.annotationEditFormatter.format(doc, edits);
}
- private AnnotationEditFormatter getAnnotationEditFormatter() {
- return this.annotationEditFormatter;
+ protected CompilationUnit buildASTRoot() {
+ return JDTTools.buildASTRoot(this.compilationUnit);
}
- private CommandExecutor getModifySharedDocumentCommandExecutor() {
+ protected CommandExecutor getModifySharedDocumentCommandExecutor() {
return this.modifySharedDocumentCommandExecutorProvider.getCommandExecutor();
}
@@ -194,11 +211,11 @@ public abstract class JDTMember
* simple command that calls back to the member to apply the edits
* in the same way as if the document were not shared
*/
- class ModifySharedDocumentCommand implements Command {
+ protected class ModifySharedDocumentCommand implements Command {
private final TextEdit edits;
private final IDocument doc;
- ModifySharedDocumentCommand(TextEdit edits, IDocument doc) {
+ protected ModifySharedDocumentCommand(TextEdit edits, IDocument doc) {
super();
this.edits = edits;
this.doc = doc;
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMethodAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMethodAttribute.java
index dc86ae772b..d0844d6606 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMethodAttribute.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTMethodAttribute.java
@@ -10,19 +10,26 @@
package org.eclipse.jpt.core.internal.utility.jdt;
import java.beans.Introspector;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.JavaModelException;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.core.utility.jdt.AnnotationEditFormatter;
import org.eclipse.jpt.core.utility.jdt.MethodAttribute;
+import org.eclipse.jpt.core.utility.jdt.Type;
import org.eclipse.jpt.utility.CommandExecutorProvider;
+import org.eclipse.jpt.utility.JavaType;
+import org.eclipse.jpt.utility.MethodSignature;
+import org.eclipse.jpt.utility.internal.SimpleMethodSignature;
/**
- * Adapt and extend a jdt method.
+ * Adapt and extend a JDT method.
* Attribute based on a Java property, e.g.
* private int getFoo() {
* return foo;
@@ -30,68 +37,129 @@ import org.eclipse.jpt.utility.CommandExecutorProvider;
* private void setFoo(int foo) {
* this.foo = foo;
* }
- *
- * For now we only hold the getter method, since that's where the
- * annotations are put.
*/
public class JDTMethodAttribute
extends JDTAttribute
implements MethodAttribute
{
+ /** we need the parameter types to build the method signature */
+ private final JavaType[] parameterTypes;
+
- public JDTMethodAttribute(IMethod getMethod, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
- super(getMethod, modifySharedDocumentCommandExecutorProvider);
+ // ********** constructors **********
+
+ public static JDTMethodAttribute newInstance(
+ Type declaringType,
+ MethodSignature signature,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
+ return newInstance(declaringType, signature, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, DefaultAnnotationEditFormatter.instance());
}
-
- public JDTMethodAttribute(IMethod getMethod, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider, AnnotationEditFormatter annotationEditFormatter) {
- super(getMethod, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
+
+ public static JDTMethodAttribute newInstance(
+ Type declaringType,
+ MethodSignature signature,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
+ AnnotationEditFormatter annotationEditFormatter) {
+ return new JDTMethodAttribute(declaringType, signature, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
}
- @Override
- public IMethod getJdtMember() {
- return (IMethod) super.getJdtMember();
+ public JDTMethodAttribute(
+ Type declaringType,
+ MethodSignature methodSignature,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
+ this(declaringType, methodSignature, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, DefaultAnnotationEditFormatter.instance());
}
-
- // ********** Member implementation **********
+ public JDTMethodAttribute(
+ Type declaringType,
+ MethodSignature methodSignature,
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
+ AnnotationEditFormatter annotationEditFormatter) {
+ super(declaringType, methodSignature.getName(), occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
+ this.parameterTypes = methodSignature.getParameterTypes();
+ }
+
+ /**
+ * constructor for testing
+ */
+ public JDTMethodAttribute(Type declaringType, String name, String[] parameterTypeNames, int occurrence, ICompilationUnit compilationUnit) {
+ this(declaringType, new SimpleMethodSignature(name, parameterTypeNames), occurrence, compilationUnit, CommandExecutorProvider.Default.instance(), DefaultAnnotationEditFormatter.instance());
+ }
+
+
+ // ********** Member/Attribute/MethodAttribute implementation **********
+
+ public IMethodBinding getBinding(CompilationUnit astRoot) {
+ return this.getBodyDeclaration(astRoot).resolveBinding();
+ }
public MethodDeclaration getBodyDeclaration(CompilationUnit astRoot) {
- try {
- return ASTNodeSearchUtil.getMethodDeclarationNode(getJdtMember(), astRoot);
- } catch(JavaModelException e) {
- throw new RuntimeException(e);
+ int count = 0;
+ for (MethodDeclaration methodDeclaration : this.getDeclaringTypeMethodDeclarations(astRoot)) {
+ if (this.matches(methodDeclaration)) {
+ count++;
+ if (count == this.getOccurrence()) {
+ return methodDeclaration;
+ }
+ }
}
+ // return null if the method 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;
}
-
- public IMethodBinding getBinding(CompilationUnit astRoot) {
- return getBodyDeclaration(astRoot).resolveBinding();
+
+ public boolean matches(MethodSignature signature, int occurrence) {
+ return this.matches(signature) && (occurrence == this.getOccurrence());
}
-
- public TextRange getNameTextRange(CompilationUnit astRoot) {
- return new ASTNodeTextRange(getBodyDeclaration(astRoot).getName());
+
+ protected boolean matches(MethodSignature signature) {
+ return signature.getName().equals(this.getName_())
+ && Arrays.equals(this.parameterTypes, signature.getParameterTypes());
}
- // ********** Attribute implementation **********
+ protected boolean matches(MethodDeclaration methodDeclaration) {
+ return this.matches(JDTTools.buildMethodSignature(methodDeclaration));
+ }
+
+ // minimize scope of suppressed warnings
+ @SuppressWarnings("unchecked")
+ protected static List<SingleVariableDeclaration> parameters(MethodDeclaration methodDeclaration) {
+ return methodDeclaration.parameters();
+ }
@Override
- public boolean isMethod() {
- return true;
+ public boolean matches(String memberName, int occurrence) {
+ throw new UnsupportedOperationException("Use #matches(org.eclipse.jdt.core.dom.MethodDeclaration, int).");
+ }
+
+ public TextRange getNameTextRange(CompilationUnit astRoot) {
+ return new ASTNodeTextRange(this.getBodyDeclaration(astRoot).getName());
}
/**
- * "foo" returned for a method named "getFoo" or "isFoo"
+ * return "foo" for a method named "getFoo" or "isFoo"
*/
public String getAttributeName() {
- String methodName = super.getName();
+ String name = this.getName_();
int beginIndex = 0;
- if (methodName.startsWith("get")) {
+ if (name.startsWith("get")) {
beginIndex = 3;
- } else if (methodName.startsWith("is")) {
+ } else if (name.startsWith("is")) {
beginIndex = 2;
}
- return Introspector.decapitalize(methodName.substring(beginIndex));
+ return Introspector.decapitalize(name.substring(beginIndex));
}
-
+
public ITypeBinding getTypeBinding(CompilationUnit astRoot) {
IMethodBinding methodBinding = getBodyDeclaration(astRoot).resolveBinding();
if (methodBinding != null) {
@@ -99,4 +167,22 @@ public class JDTMethodAttribute
}
return null;
}
+
+ @Override
+ public boolean isMethod() {
+ return true;
+ }
+
+ public boolean isPersistable(CompilationUnit astRoot) {
+ IMethodBinding binding = this.getBinding(astRoot);
+ return (binding == null) ? false : JPTTools.methodIsPersistablePropertyGetter(binding);
+ }
+
+
+ // ********** internal **********
+
+ protected MethodDeclaration[] getDeclaringTypeMethodDeclarations(CompilationUnit astRoot) {
+ return this.getDeclaringTypeDeclaration(astRoot).getMethods();
+ }
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTModifiedDeclaration.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTModifiedDeclaration.java
index 361d1c2ec8..266fa7c8a0 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTModifiedDeclaration.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTModifiedDeclaration.java
@@ -13,7 +13,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Annotation;
@@ -88,10 +87,6 @@ public class JDTModifiedDeclaration
return (ICompilationUnit) this.getCompilationUnit().getJavaElement();
}
- public IType getType() {
- return this.getCompilationUnit().getTypeRoot().findPrimaryType();
- }
-
/**
* Return the declaration's annotations.
*/
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTTools.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTTools.java
index f440d5647d..2050011ede 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTTools.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTTools.java
@@ -9,9 +9,9 @@
******************************************************************************/
package org.eclipse.jpt.core.internal.utility.jdt;
-import org.eclipse.jdt.core.IClassFile;
+import java.util.List;
+
import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
@@ -22,62 +22,26 @@ import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TypeLiteral;
+import org.eclipse.jpt.utility.JavaType;
+import org.eclipse.jpt.utility.MethodSignature;
+import org.eclipse.jpt.utility.internal.SimpleJavaType;
+import org.eclipse.jpt.utility.internal.SimpleMethodSignature;
public class JDTTools {
- // TODO get rid of the "lightweight" methods after reworking how
- // ValidationMessages determine line numbers
/**
- * Build an AST for the specified member's compilation unit or
- * (source-attached) class file. Build the AST without its bindings
- * resolved.
- */
- public static CompilationUnit buildLightweightASTRoot(IMember member) {
- return buildASTRoot(member, false);
- }
-
- /**
- * Build an AST for the specified member's compilation unit or
- * (source-attached) class file. Build the AST with its bindings
+ * Build an AST for the specified compilation unit with its bindings
* resolved (and the resultant performance hit).
*/
- public static CompilationUnit buildASTRoot(IMember member) {
- return buildASTRoot(member, true);
- }
-
- /**
- * Build an AST for the specified member's compilation unit or
- * (source-attached) class file.
- */
- private static CompilationUnit buildASTRoot(IMember member, boolean resolveBindings) {
- return (member.isBinary()) ?
- buildASTRoot(member.getClassFile(), resolveBindings) // the class file must have a source attachment
- :
- buildASTRoot(member.getCompilationUnit(), resolveBindings);
- }
-
- public static CompilationUnit buildASTRoot(IClassFile classFile) {
- return buildASTRoot(classFile, true);
- }
-
- private static CompilationUnit buildASTRoot(IClassFile classFile, boolean resolveBindings) {
- ASTParser parser = ASTParser.newParser(AST.JLS3);
- parser.setSource(classFile);
- parser.setResolveBindings(resolveBindings);
- return (CompilationUnit) parser.createAST(null);
- }
-
public static CompilationUnit buildASTRoot(ICompilationUnit compilationUnit) {
- return buildASTRoot(compilationUnit, true);
- }
-
- private static CompilationUnit buildASTRoot(ICompilationUnit compilationUnit, boolean resolveBindings) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(compilationUnit);
- parser.setResolveBindings(resolveBindings);
- parser.setBindingsRecovery(true); //see bugs 196200, 222735
+ parser.setResolveBindings(true);
+ parser.setBindingsRecovery(true); // see bugs 196200, 222735
return (CompilationUnit) parser.createAST(null);
}
@@ -128,4 +92,28 @@ public class JDTTools {
return null;
}
+ public static MethodSignature buildMethodSignature(MethodDeclaration methodDeclaration) {
+ return new SimpleMethodSignature(
+ methodDeclaration.getName().getFullyQualifiedName(),
+ buildParameterTypes(methodDeclaration)
+ );
+ }
+
+ public static JavaType[] buildParameterTypes(MethodDeclaration methodDeclaration) {
+ List<SingleVariableDeclaration> parameters = parameters(methodDeclaration);
+ int len = parameters.size();
+ JavaType[] parameterTypes = new JavaType[len];
+ for (int i = 0; i < len; i++) {
+ ITypeBinding type = parameters.get(i).getType().resolveBinding();
+ parameterTypes[i] = new SimpleJavaType(type.getQualifiedName(), type.getDimensions());
+ }
+ return parameterTypes;
+ }
+
+ // minimize scope of suppressed warnings
+ @SuppressWarnings("unchecked")
+ private static List<SingleVariableDeclaration> parameters(MethodDeclaration methodDeclaration) {
+ return methodDeclaration.parameters();
+ }
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTType.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTType.java
index 7f276aca1c..22ca6c302b 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTType.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JDTType.java
@@ -9,121 +9,167 @@
******************************************************************************/
package org.eclipse.jpt.core.internal.utility.jdt;
-import java.util.ArrayList;
import java.util.List;
-import org.eclipse.jdt.core.IField;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
-import org.eclipse.jdt.core.dom.BodyDeclaration;
+
+import org.eclipse.jdt.core.ICompilationUnit;
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.MethodDeclaration;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.core.utility.jdt.AnnotationEditFormatter;
import org.eclipse.jpt.core.utility.jdt.Type;
import org.eclipse.jpt.utility.CommandExecutorProvider;
+/**
+ * Adapt and extend a JDT type.
+ */
public class JDTType
extends JDTMember
implements Type
{
- public JDTType(IType type, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
- super(type, modifySharedDocumentCommandExecutorProvider);
+ /**
+ * constructor for the compilation unit's primary type
+ */
+ public JDTType(
+ TypeDeclaration typeDeclaration, // exclude annotations and enums
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
+ this(typeDeclaration, compilationUnit, modifySharedDocumentCommandExecutorProvider, DefaultAnnotationEditFormatter.instance());
}
- public JDTType(IType type, CommandExecutorProvider modifySharedDocumentCommandExecutorProvider, AnnotationEditFormatter annotationEditFormatter) {
- super(type, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
+ /**
+ * constructor for the compilation unit's primary type
+ */
+ public JDTType(
+ TypeDeclaration typeDeclaration, // exclude annotations and enums
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
+ AnnotationEditFormatter annotationEditFormatter) {
+ this(null, typeDeclaration, 1, compilationUnit, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
}
- @Override
- public IType getJdtMember() {
- return (IType) super.getJdtMember();
+ /**
+ * constructor for nested types
+ */
+ public JDTType(
+ Type declaringType,
+ TypeDeclaration typeDeclaration, // exclude annotations and enums
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider) {
+ this(declaringType, typeDeclaration, occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, DefaultAnnotationEditFormatter.instance());
}
- public IType[] jdtTypes() {
- try {
- return getJdtMember().getTypes();
- }
- catch(JavaModelException e) {
- throw new RuntimeException(e);
- }
+ /**
+ * constructor for nested types
+ */
+ public JDTType(
+ Type declaringType,
+ TypeDeclaration typeDeclaration, // exclude annotations and enums
+ int occurrence,
+ ICompilationUnit compilationUnit,
+ CommandExecutorProvider modifySharedDocumentCommandExecutorProvider,
+ AnnotationEditFormatter annotationEditFormatter) {
+ super(declaringType, typeDeclaration.getName().getFullyQualifiedName(), occurrence, compilationUnit, modifySharedDocumentCommandExecutorProvider, annotationEditFormatter);
}
-
- public IField[] jdtFields() {
- try {
- return getJdtMember().getFields();
- }
- catch(JavaModelException e) {
- throw new RuntimeException(e);
- }
+
+ /**
+ * constructor for testing
+ */
+ public JDTType(Type declaringType, String name, int occurrence, ICompilationUnit compilationUnit) {
+ super(declaringType, name, occurrence, compilationUnit, CommandExecutorProvider.Default.instance(), DefaultAnnotationEditFormatter.instance());
}
-
- public IMethod[] jdtMethods() {
- try {
- return getJdtMember().getMethods();
- }
- catch(JavaModelException e) {
- throw new RuntimeException(e);
- }
+
+
+ // ********** Member/Type implementation **********
+
+ public ITypeBinding getBinding(CompilationUnit astRoot) {
+ return this.getBodyDeclaration(astRoot).resolveBinding();
}
-
- // ********** Member implementation **********
- public AbstractTypeDeclaration getBodyDeclaration(CompilationUnit astRoot) {
- Type declaringType = this.declaringType();
- if (declaringType != null) {
- return this.getTypeDeclaration(declaringType.getBodyDeclaration(astRoot));
- }
- return this.getTypeDeclaration(this.types(astRoot));
+ /**
+ * find the type's body declaration in the specified AST
+ */
+ public TypeDeclaration getBodyDeclaration(CompilationUnit astRoot) {
+ Type declaringType = this.getDeclaringType();
+ return (declaringType == null) ?
+ this.getTopLevelTypeDeclaration(astRoot)
+ :
+ this.getNestedTypeDeclaration(declaringType.getBodyDeclaration(astRoot));
}
-
- public AbstractTypeDeclaration getTypeDeclaration(AbstractTypeDeclaration declaringTypeDeclaration) {
- return getTypeDeclaration(this.types(declaringTypeDeclaration));
+
+ public boolean isPersistable(CompilationUnit astRoot) {
+ ITypeBinding binding = this.getBinding(astRoot);
+ return (binding == null) ? false : JPTTools.typeIsPersistable(binding);
}
-
- private AbstractTypeDeclaration getTypeDeclaration(List<AbstractTypeDeclaration> typeDeclarations) {
- String name = this.getName();
- for (AbstractTypeDeclaration typeDeclaration : typeDeclarations) {
- if (typeDeclaration.getName().getFullyQualifiedName().equals(name)) {
- return typeDeclaration;
- }
- }
- return null;
+
+ public TextRange getNameTextRange(CompilationUnit astRoot) {
+ return new ASTNodeTextRange(this.getBodyDeclaration(astRoot).getName());
}
- public ITypeBinding getBinding(CompilationUnit astRoot) {
- return getBodyDeclaration(astRoot).resolveBinding();
+ public TypeDeclaration[] getTypes(CompilationUnit astRoot) {
+ return this.getBodyDeclaration(astRoot).getTypes();
}
- public TextRange getNameTextRange(CompilationUnit astRoot) {
- return new ASTNodeTextRange(getBodyDeclaration(astRoot).getName());
+ public FieldDeclaration[] getFields(CompilationUnit astRoot) {
+ return this.getBodyDeclaration(astRoot).getFields();
}
- // ********** miscellaneous **********
+ public MethodDeclaration[] getMethods(CompilationUnit astRoot) {
+ return this.getBodyDeclaration(astRoot).getMethods();
+ }
- @SuppressWarnings("unchecked")
- protected List<AbstractTypeDeclaration> types(CompilationUnit astRoot) {
- return astRoot.types();
+
+ // ********** internal **********
+
+ /**
+ * return the first top-level type in the specified AST with a matching name
+ */
+ protected TypeDeclaration getTopLevelTypeDeclaration(CompilationUnit astRoot) {
+ return this.getTypeDeclaration(types(astRoot));
+ }
+
+ protected TypeDeclaration getTypeDeclaration(List<TypeDeclaration> typeDeclarations) {
+ return this.getTypeDeclaration(typeDeclarations.toArray(new TypeDeclaration[typeDeclarations.size()]));
+ }
+
+ /**
+ * return the nested type with a matching name and occurrence
+ */
+ protected TypeDeclaration getNestedTypeDeclaration(TypeDeclaration declaringTypeDeclaration) {
+ return this.getTypeDeclaration(declaringTypeDeclaration.getTypes());
}
-
- protected List<AbstractTypeDeclaration> types(AbstractTypeDeclaration typeDeclaration) {
- List<AbstractTypeDeclaration> typeDeclarations = new ArrayList<AbstractTypeDeclaration>();
- for (BodyDeclaration bodyDeclaration : bodyDeclarations(typeDeclaration))
- if (bodyDeclaration.getNodeType() == ASTNode.TYPE_DECLARATION ||
- bodyDeclaration.getNodeType() == ASTNode.ANNOTATION_TYPE_DECLARATION ||
- bodyDeclaration.getNodeType() == ASTNode.ENUM_DECLARATION) {
- typeDeclarations.add((AbstractTypeDeclaration) bodyDeclaration);
+
+ /**
+ * return the type declaration corresponding to the type from the specified
+ * set of type declarations (match name and occurrence)
+ */
+ protected TypeDeclaration getTypeDeclaration(TypeDeclaration[] typeDeclarations) {
+ String name = this.getName_();
+ int occurrence = this.getOccurrence();
+ int count = 0;
+ for (TypeDeclaration typeDeclaration : typeDeclarations) {
+ if (typeDeclaration.getName().getFullyQualifiedName().equals(name)) {
+ count++;
+ if (count == occurrence) {
+ return typeDeclaration;
+ }
}
- return typeDeclarations;
+ }
+ // return null if the type 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;
}
-
+
+ // minimize scope of suppressed warnings
@SuppressWarnings("unchecked")
- protected List<BodyDeclaration> bodyDeclarations(AbstractTypeDeclaration typeDeclaration) {
- return typeDeclaration.bodyDeclarations();
+ protected static List<TypeDeclaration> types(CompilationUnit astRoot) {
+ return astRoot.types();
}
-
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JPTTools.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JPTTools.java
index 8726b19526..dcaed04e05 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JPTTools.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/JPTTools.java
@@ -179,8 +179,4 @@ public class JPTTools {
return true;
}
- public static boolean typeIsAbstract(ITypeBinding typeBinding) {
- return Modifier.isAbstract(typeBinding.getModifiers());
- }
-
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/NodeFinder.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/NodeFinder.java
deleted file mode 100644
index 04d0895690..0000000000
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/NodeFinder.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
- * 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:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jpt.core.internal.utility.jdt;
-
-import org.eclipse.jdt.core.ISourceRange;
-import org.eclipse.jdt.core.dom.ASTNode;
-/**
- * For a give range finds the node covered and the node covering.
- *
- * @since 2.1
- */
-//copied from org.eclipse.jdt.internal.corext.dom.NodeFinder
-//deleted code to limit the number of classes I had to copy
-public class NodeFinder extends GenericVisitor {
-
- /**
- * A visitor that maps a selection to a given ASTNode. The result node is
- * determined as follows:
- * <ul>
- * <li>first the visitor tries to find a node with the exact start and length</li>
- * <li>if no such node exists than the node that encloses the range defined by
- * start and end is returned.</li>
- * <li>if the length is zero than also nodes are considered where the node's
- * start or end position matches <code>start</code>.</li>
- * <li>otherwise <code>null</code> is returned.</li>
- * </ul>
- *
- * @param root the root node from which the search starts
- * @param start the start offset
- * @param length the length
- *
- * @return the result node
- *
- * @since 2.1
- */
- public static ASTNode perform(ASTNode root, int start, int length) {
- NodeFinder finder= new NodeFinder(start, length);
- root.accept(finder);
- ASTNode result= finder.getCoveredNode();
- if (result == null || result.getStartPosition() != start || result.getLength() != length) {
- return finder.getCoveringNode();
- }
- return result;
- }
-
- public static ASTNode perform(ASTNode root, ISourceRange range) {
- return perform(root, range.getOffset(), range.getLength());
- }
-
- private int fStart;
- private int fEnd;
-
- private ASTNode fCoveringNode;
- private ASTNode fCoveredNode;
-
- public NodeFinder(int offset, int length) {
- super(true); // include Javadoc tags
- fStart= offset;
- fEnd= offset + length;
- }
-
- @Override
- protected boolean visitNode(ASTNode node) {
- int nodeStart= node.getStartPosition();
- int nodeEnd= nodeStart + node.getLength();
- if (nodeEnd < fStart || fEnd < nodeStart) {
- return false;
- }
- if (nodeStart <= fStart && fEnd <= nodeEnd) {
- fCoveringNode= node;
- }
- if (fStart <= nodeStart && nodeEnd <= fEnd) {
- if (fCoveringNode == node) { // nodeStart == fStart && nodeEnd == fEnd
- fCoveredNode= node;
- return true; // look further for node with same length as parent
- } else if (fCoveredNode == null) { // no better found
- fCoveredNode= node;
- }
- return false;
- }
- return true;
- }
-
- /**
- * Returns the covered node. If more than one nodes are covered by the selection, the
- * returned node is first covered node found in a top-down traversal of the AST
- * @return ASTNode
- */
- public ASTNode getCoveredNode() {
- return fCoveredNode;
- }
-
- /**
- * Returns the covering node. If more than one nodes are covering the selection, the
- * returned node is last covering node found in a top-down traversal of the AST
- * @return ASTNode
- */
- public ASTNode getCoveringNode() {
- return fCoveringNode;
- }
-
-}
-
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResource.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResource.java
index 565c5952d9..cfee949099 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResource.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResource.java
@@ -131,6 +131,8 @@ public abstract class JpaXmlResource extends TranslatorResourceImpl
public abstract void javaElementChanged(ElementChangedEvent event);
+ public abstract void updateFromResource();
+
public JpaXmlResourceModel getResourceModel() {
return this.resourceModel;
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResourceModel.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResourceModel.java
index f5c0060c98..42fabbd300 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResourceModel.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/common/JpaXmlResourceModel.java
@@ -50,21 +50,24 @@ public abstract class JpaXmlResourceModel extends AbstractResourceModel
return new ReloadListener(resource);
}
- @Override
public JpaXmlResource getResource() {
return this.resource;
}
public void javaElementChanged(ElementChangedEvent event) {
- getResource().javaElementChanged(event);
+ this.resource.javaElementChanged(event);
+ }
+
+ public void updateFromResource() {
+ this.resource.updateFromResource();
}
public void addResourceModelChangeListener(ResourceModelListener listener) {
- getResource().addResourceModelChangeListener(listener);
+ this.resource.addResourceModelChangeListener(listener);
}
public void removeResourceModelChangeListener(ResourceModelListener listener) {
- getResource().removeResourceModelChangeListener(listener);
+ this.resource.removeResourceModelChangeListener(listener);
}
@Override
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceModel.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceModel.java
index 00b803af45..22bc7d0427 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceModel.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceModel.java
@@ -22,7 +22,7 @@ import org.eclipse.jpt.core.ResourceModel;
*/
public interface JavaResourceModel extends ResourceModel {
- JpaCompilationUnit getResource();
+ JpaCompilationUnit getJpaCompilationUnit();
void resourceChanged();
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceNode.java
index d0402fd7c3..9574f0874e 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceNode.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourceNode.java
@@ -10,9 +10,7 @@
package org.eclipse.jpt.core.resource.java;
import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jpt.core.JpaAnnotationProvider;
import org.eclipse.jpt.core.utility.TextRange;
-import org.eclipse.jpt.utility.CommandExecutorProvider;
import org.eclipse.jpt.utility.model.Model;
/**
@@ -24,22 +22,16 @@ import org.eclipse.jpt.utility.model.Model;
* pioneering adopters on the understanding that any code that uses this API
* will almost certainly be broken (repeatedly) as the API evolves.
*/
-public interface JavaResourceNode extends Model
-{
+public interface JavaResourceNode extends Model {
+
void initialize(CompilationUnit astRoot);
-
+
JavaResourceModel getResourceModel();
-
+
JpaCompilationUnit getJpaCompilationUnit();
-
- JpaAnnotationProvider getAnnotationProvider();
-
- CommandExecutorProvider getModifySharedDocumentCommandExecutorProvider();
-
+
void updateFromJava(CompilationUnit astRoot);
-
- /**
- * Return the ITextRange
- */
+
TextRange getTextRange(CompilationUnit astRoot);
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentMember.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentMember.java
index ef35bd26f9..234cbd259b 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentMember.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentMember.java
@@ -11,9 +11,9 @@ package org.eclipse.jpt.core.resource.java;
import java.util.Iterator;
import java.util.ListIterator;
-import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.utility.TextRange;
+import org.eclipse.jpt.utility.MethodSignature;
/**
*
@@ -34,8 +34,7 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
* <p>Does not return duplicate annotations as this error is handled by the java compiler.
*/
<T extends JavaResourceNode> Iterator<T> mappingAnnotations();
-
- String MAPPING_ANNOTATIONS_COLLECTION = "mappingAnnotationsCollection";
+ String MAPPING_ANNOTATIONS_COLLECTION = "mappingAnnotations";
int mappingAnnotationsSize();
/**
@@ -43,7 +42,6 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
* In the case of multiples the first one will be returned as defined by the order of
* {@link org.eclipse.jpt.core.internal.platform.GenericJpaPlatform#typeMappingAnnotationDefinitions()} or
* {@link org.eclipse.jpt.core.internal.platform.GenericJpaPlatform#attributeMappingAnnotationDefinitions()}
- * @return
*/
JavaResourceNode getMappingAnnotation();
@@ -53,7 +51,6 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
* and "javax.persistence.MappedSuperclass"
* Return the first if there are duplicates in the source code
* @param annotationName - fully qualified annotation name
- * @return
*/
//TODO not sure we need this API, first 2 seem sufficient
JavaResourceNode getMappingAnnotation(String annotationName);
@@ -74,7 +71,7 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
*/
<T extends JavaResourceNode> Iterator<T> annotations();
- String ANNOTATIONS_COLLECTION = "annotationsCollection";
+ String ANNOTATIONS_COLLECTION = "annotations";
int annotationsSize();
@@ -92,8 +89,6 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
/**
* Returns the <code>JavaResource</code> with this fully qualifed annotation name.
* Return the first if there are duplicates in the source code.
- * @param annotationName
- * @return
*/
JavaResourceNode getAnnotation(String annotationName);
@@ -101,8 +96,6 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
* Returns the <code>JavaResource</code> with this fully qualifed annotation name.
* Return the first if there are duplicates in the source code. Will not return null,
* but a null Object instead if no annotation with this name exists in the java source.
- * @param annotationName
- * @return
*/
JavaResourceNode getNonNullAnnotation(String annotationName);
@@ -110,8 +103,6 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
* Return a null implementation of <code>JavaResourceNode</code> with this fully qualifed annotation name.
* The corresponding AnnotationDefinition needs to implement buildNullAnnotation()
* {@link AnnotationDefinition#buildNullAnnotation(JavaResourcePersistentMember, org.eclipse.jpt.core.internal.jdtutility.Member)}
- * @param annotationName
- * @return
*/
JavaResourceNode getNullMappingAnnotation(String annotationName);
@@ -142,10 +133,9 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
/**
* Return whether the underlying JDT member is persistable according to the JPA spec
- * @return
*/
boolean isPersistable();
- String PERSISTABLE_PROPERTY = "persistableProperty";
+ String PERSISTABLE_PROPERTY = "persistable";
/**
* Return whether the underlying JDT member is currently annotated as being persistent
@@ -154,13 +144,17 @@ public interface JavaResourcePersistentMember extends JavaResourceNode
boolean isPersisted();
/**
- * Return true if this JavaPersistentResource represents the underlying JDT IMeber
- * @param member
- * @return
+ * Return whether the Java resource persistent member is for the specified
+ * member.
*/
- boolean isFor(IMember member);
-
-
+ boolean isFor(String memberName, int occurrence);
+
+ /**
+ * Return whether the Java resource persistent member is for the specified
+ * method.
+ */
+ boolean isFor(MethodSignature methodSignature, int occurrence);
+
/**
* return the text range for the name of the persistent resource
*/
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentType.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentType.java
index 114692a64a..f71a3f3849 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentType.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JavaResourcePersistentType.java
@@ -24,25 +24,23 @@ import org.eclipse.jpt.core.utility.jdt.Member;
public interface JavaResourcePersistentType extends JavaResourcePersistentMember
{
/**
- * Return only the persistable nestedTypes
+ * Return only the immediately nested persistable nestedTypes
*/
Iterator<JavaResourcePersistentType> nestedTypes();
- String NESTED_TYPES_COLLECTION = "nestedTypesCollection";
+ String NESTED_TYPES_COLLECTION = "nestedTypes";
/**
* Return only the persistable attributes, those that respond true to
* {@link JavaResourcePersistentAttribute#isPersistable()}
* This returns fields and properties
- * @return
*/
Iterator<JavaResourcePersistentAttribute> attributes();
- String ATTRIBUTES_COLLECTION = "attributesCollection";
+ String ATTRIBUTES_COLLECTION = "attributes";
/**
* Return only the persistable fields, those that respond true to
* {@link JavaResourcePersistentAttribute#isPersistable()}
* This returns filters out all properties and only returns fields
- * @return
*/
Iterator<JavaResourcePersistentAttribute> fields();
@@ -50,32 +48,32 @@ public interface JavaResourcePersistentType extends JavaResourcePersistentMember
* Return only the persistable fields, those that respond true to
* {@link JavaResourcePersistentAttribute#isPersistable()}
* This returns filters out all fields and only returns properties
- * @return
*/
Iterator<JavaResourcePersistentAttribute> properties();
+ // TODO rename to getJavaResourcePersistentType(String)
JavaResourcePersistentType getJavaPersistentTypeResource(String fullyQualifiedTypeName);
/**
* Return the fully qualified type name
*/
String getQualifiedName();
- String QUALIFIED_NAME_PROPERTY = "qualifiedNameProperty";
+ String QUALIFIED_NAME_PROPERTY = "qualifiedName";
/**
* Return the fully unqualified type name
*/
String getName();
- String NAME_PROPERTY = "nameProperty";
+ String NAME_PROPERTY = "name";
String getSuperClassQualifiedName();
- String SUPER_CLASS_QUALIFIED_NAME_PROPERTY = "superClassQualifiedNameProperty";
+ String SUPER_CLASS_QUALIFIED_NAME_PROPERTY = "superClassQualifiedName";
AccessType getAccess();
- String ACCESS_PROPERTY = "accessProperty";
+ String ACCESS_PROPERTY = "access";
boolean isAbstract();
- String ABSTRACT_PROPERTY = "abstractProperty";
+ String ABSTRACT_PROPERTY = "abstract";
Member getMember();
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JpaCompilationUnit.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JpaCompilationUnit.java
index 8d4a96ed81..d6e88f793e 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JpaCompilationUnit.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/JpaCompilationUnit.java
@@ -10,7 +10,9 @@
package org.eclipse.jpt.core.resource.java;
import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jpt.core.JpaAnnotationProvider;
import org.eclipse.jpt.core.utility.jdt.AnnotationEditFormatter;
+import org.eclipse.jpt.utility.CommandExecutorProvider;
/**
*
@@ -26,9 +28,15 @@ public interface JpaCompilationUnit extends JavaResourceNode {
ICompilationUnit getCompilationUnit();
JavaResourcePersistentType getPersistentType();
+ String PERSISTENT_TYPE_PROPERTY = "persistentType";
+ // TODO rename getJavaResourcePersistentType(String)
JavaResourcePersistentType getJavaPersistentTypeResource(String typeName);
+ JpaAnnotationProvider getAnnotationProvider();
+
+ CommandExecutorProvider getModifySharedDocumentCommandExecutorProvider();
+
AnnotationEditFormatter getAnnotationEditFormatter();
void resourceChanged();
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/orm/OrmResource.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/orm/OrmResource.java
index 0aa1f932ed..af0199ce33 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/orm/OrmResource.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/orm/OrmResource.java
@@ -41,7 +41,12 @@ public class OrmResource extends JpaXmlResource
@Override
public void javaElementChanged(ElementChangedEvent event) {
- // TODO Auto-generated method stub
+ // TODO
+ }
+
+ @Override
+ public void updateFromResource() {
+ // TODO
}
public XmlEntityMappings getEntityMappings() {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/persistence/PersistenceResource.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/persistence/PersistenceResource.java
index e8e5450eda..2089873bf7 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/persistence/PersistenceResource.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/persistence/PersistenceResource.java
@@ -41,7 +41,12 @@ public class PersistenceResource extends JpaXmlResource
@Override
public void javaElementChanged(ElementChangedEvent event) {
- // TODO Auto-generated method stub
+ // TODO
+ }
+
+ @Override
+ public void updateFromResource() {
+ // TODO
}
public XmlPersistence getPersistence() {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Attribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Attribute.java
index ce89b36409..c4e917a82c 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Attribute.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Attribute.java
@@ -13,6 +13,8 @@ import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
/**
+ * Attributes are either represented by fields ('foo') or properties/method
+ * pairs ('getFoo()'/'setFoo()').
*
* Provisional API: This interface is part of an interim API that is still
* under development and expected to change significantly before reaching
@@ -24,6 +26,11 @@ import org.eclipse.jdt.core.dom.ITypeBinding;
*/
public interface Attribute extends Member {
+ /**
+ * Return the attribute's name, as opposed to the member's name
+ * (e.g. "getFoo()" returns "foo").
+ */
+ // TODO rename to getName()?
String getAttributeName();
/**
@@ -32,8 +39,15 @@ public interface Attribute extends Member {
*/
ITypeBinding getTypeBinding(CompilationUnit astRoot);
+ /**
+ * Return whether the attribute is a field.
+ */
boolean isField();
+ /**
+ * Return whether the attribute is a property/method pair.
+ */
+ // TODO rename to isProperty()?
boolean isMethod();
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/FieldAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/FieldAttribute.java
index 2d92f48d94..4046cf9f49 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/FieldAttribute.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/FieldAttribute.java
@@ -10,9 +10,11 @@
package org.eclipse.jpt.core.utility.jdt;
import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IVariableBinding;
/**
+ * Field attribute: just some covariant overrides.
*
* Provisional API: This interface is part of an interim API that is still
* under development and expected to change significantly before reaching
@@ -24,6 +26,14 @@ import org.eclipse.jdt.core.dom.IVariableBinding;
*/
public interface FieldAttribute extends Attribute {
+ /**
+ * Covariant override.
+ */
IVariableBinding getBinding(CompilationUnit astRoot);
+ /**
+ * Covariant override.
+ */
+ FieldDeclaration getBodyDeclaration(CompilationUnit astRoot);
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Member.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Member.java
index 0d1a28831f..d36bbf6862 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Member.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Member.java
@@ -9,13 +9,14 @@
******************************************************************************/
package org.eclipse.jpt.core.utility.jdt;
-import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jpt.core.utility.TextRange;
/**
+ * Dali manipulates annotations on members (types, fields, and methods).
+ * This interface simplifies those manipulations.
*
* Provisional API: This interface is part of an interim API that is still
* under development and expected to change significantly before reaching
@@ -27,23 +28,47 @@ import org.eclipse.jpt.core.utility.TextRange;
*/
public interface Member {
- boolean wraps(IMember member);
-
- CompilationUnit getAstRoot();
-
/**
- * Return the member's body declaration.
+ * Return the member's body declaration from the specified AST.
+ * This can be null if the member is no longer present in the AST
+ * because the source has been changed in another thread.
*/
BodyDeclaration getBodyDeclaration(CompilationUnit astRoot);
+ /**
+ * Return the member's binding from the specified AST.
+ */
IBinding getBinding(CompilationUnit astRoot);
+ /**
+ * Return the member's "modified" declaration from the specified AST.
+ */
+ ModifiedDeclaration getModifiedDeclaration(CompilationUnit astRoot);
+
+ /**
+ * Return the member's "modified" declaration from a newly-generated AST.
+ */
ModifiedDeclaration getModifiedDeclaration();
- ModifiedDeclaration getModifiedDeclaration(CompilationUnit astRoot);
+ /**
+ * Return whether the attribute is a persistable field or property getter.
+ */
+ boolean isPersistable(CompilationUnit astRoot);
+
+ /**
+ * Return whether the member matches the specified member
+ * and occurrence.
+ */
+ boolean matches(String memberName, int occurrence);
+ /**
+ * Return the member's name text range from the specified AST.
+ */
TextRange getNameTextRange(CompilationUnit astRoot);
+ /**
+ * Edit the member's declaration using the specified editor.
+ */
void edit(Editor editor);
@@ -51,12 +76,13 @@ public interface Member {
/**
* This interface defines a callback that is invoked when the member's
- * compilation unit is in a state to be manipulated.
+ * compilation unit/AST is in a state to be manipulated.
*/
public interface Editor {
/**
- * Edit the specified declaration.
+ * Edit the specified declaration. Any changes made to the declaration
+ * will be captured and applied to the member's compilation unit.
*/
void edit(ModifiedDeclaration declaration);
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/MethodAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/MethodAttribute.java
index 9736c1d63a..4637ab76cf 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/MethodAttribute.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/MethodAttribute.java
@@ -11,8 +11,11 @@ package org.eclipse.jpt.core.utility.jdt;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jpt.utility.MethodSignature;
/**
+ * Property attribute: just some covariant overrides.
*
* Provisional API: This interface is part of an interim API that is still
* under development and expected to change significantly before reaching
@@ -22,8 +25,22 @@ import org.eclipse.jdt.core.dom.IMethodBinding;
*
* This interface is not intended to be implemented by clients.
*/
+// TODO rename PropertyAttribute?
public interface MethodAttribute extends Attribute {
+ /**
+ * Covariant override.
+ */
IMethodBinding getBinding(CompilationUnit astRoot);
+ /**
+ * Covariant override.
+ */
+ MethodDeclaration getBodyDeclaration(CompilationUnit astRoot);
+
+ /**
+ * This method must be used instead of Member#matches(String, int).
+ */
+ boolean matches(MethodSignature signature, int occurrence);
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Type.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Type.java
index 5931c9e38f..26726d98a7 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Type.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/utility/jdt/Type.java
@@ -9,14 +9,14 @@
******************************************************************************/
package org.eclipse.jpt.core.utility.jdt;
-import org.eclipse.jdt.core.IField;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
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.MethodDeclaration;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
/**
+ * Type: just some covariant overrides.
*
* Provisional API: This interface is part of an interim API that is still
* under development and expected to change significantly before reaching
@@ -28,14 +28,29 @@ import org.eclipse.jdt.core.dom.ITypeBinding;
*/
public interface Type extends Member {
+ /**
+ * Covariant override.
+ */
ITypeBinding getBinding(CompilationUnit astRoot);
- IType[] jdtTypes();
-
- IField[] jdtFields();
-
- IMethod[] jdtMethods();
-
- AbstractTypeDeclaration getBodyDeclaration(CompilationUnit astRoot);
+ /**
+ * Covariant override.
+ */
+ TypeDeclaration getBodyDeclaration(CompilationUnit astRoot);
+
+ /**
+ * Return the type's nested types (does not include annotations or enums).
+ */
+ TypeDeclaration[] getTypes(CompilationUnit astRoot);
+
+ /**
+ * Return the type's fields.
+ */
+ FieldDeclaration[] getFields(CompilationUnit astRoot);
+
+ /**
+ * Return the type's methods.
+ */
+ MethodDeclaration[] getMethods(CompilationUnit astRoot);
}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelection.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelection.java
index a5dccd080d..4f64a64780 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelection.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/DefaultJpaSelection.java
@@ -11,13 +11,17 @@ package org.eclipse.jpt.ui.internal.selection;
import org.eclipse.jpt.core.JpaStructureNode;
+/**
+ * Straightforward implementation of the JpaSelection interface.
+ */
public class DefaultJpaSelection
implements JpaSelection
{
- private JpaStructureNode selectedNode;
+ private final JpaStructureNode selectedNode;
public DefaultJpaSelection(JpaStructureNode selectedNode) {
+ super();
if (selectedNode == null) {
throw new NullPointerException("A 'selectedNode' is required; otherwise use NULL_SELECTION.");
}
@@ -36,11 +40,11 @@ public class DefaultJpaSelection
@Override
public boolean equals(Object obj) {
- if (! (obj instanceof DefaultJpaSelection)) {
+ if (! (obj instanceof JpaSelection)) {
return false;
}
-
- return this.selectedNode.equals(((DefaultJpaSelection) obj).selectedNode);
+ JpaSelection other = (JpaSelection) obj;
+ return ( ! other.isEmpty()) && this.selectedNode.equals(other.getSelectedNode());
}
@Override
@@ -52,4 +56,5 @@ public class DefaultJpaSelection
public String toString() {
return this.selectedNode.toString();
}
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java
index 1178f05401..27046fcedc 100644
--- a/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java
+++ b/jpa/plugins/org.eclipse.jpt.ui/src/org/eclipse/jpt/ui/internal/selection/TextEditorSelectionParticipant.java
@@ -49,7 +49,7 @@ public class TextEditorSelectionParticipant
this.editorInputListener = new EditorInputListener();
this.textEditor.addPropertyListener(this.editorInputListener);
this.editorSelectionListener = new EditorSelectionListener();
- this.postSelectionProvider().addPostSelectionChangedListener(this.editorSelectionListener);
+ this.getPostSelectionProvider().addPostSelectionChangedListener(this.editorSelectionListener);
this.currentSelection = this.calculateSelection();
}
@@ -61,16 +61,16 @@ public class TextEditorSelectionParticipant
public void selectionChanged(JpaSelectionEvent evt) {
JpaSelection newSelection = evt.getSelection();
-
+
if ((newSelection == JpaSelection.NULL_SELECTION)
|| newSelection.equals(this.currentSelection)) {
return;
}
-
- if (getActiveTextEditor() != textEditor) {
+
+ if (getActiveTextEditor() != this.textEditor) {
return;
}
-
+
this.forwardSelection = false;
TextRange textRange = newSelection.getSelectedNode().getSelectionTextRange();
if (textRange != null) {
@@ -86,54 +86,57 @@ public class TextEditorSelectionParticipant
public void dispose() {
this.textEditor.removePropertyListener(this.editorInputListener);
- this.postSelectionProvider().removePostSelectionChangedListener(this.editorSelectionListener);
+ this.getPostSelectionProvider().removePostSelectionChangedListener(this.editorSelectionListener);
}
// ********** internal methods **********
- private JpaSelection calculateSelection() {
+ protected JpaSelection calculateSelection() {
ISelection selection = this.textEditor.getSelectionProvider().getSelection();
if (! (selection instanceof ITextSelection)) {
return JpaSelection.NULL_SELECTION;
}
- JpaFile jpaFile = this.jpaFile();
+ JpaFile jpaFile = this.getJpaFile();
if (jpaFile == null) {
return JpaSelection.NULL_SELECTION;
}
- JpaStructureNode selectedNode = jpaFile.getStructureNode(((ITextSelection) selection).getOffset());
- if (selectedNode == null) {
- return JpaSelection.NULL_SELECTION;
- }
+ // the resource model might be out of synch when we get this event
+ // so we force it to update before we ask it for the "selected node";
+ // TODO synchronously update the context model?
+ jpaFile.updateFromResource();
+ return this.buildSelection(jpaFile.getStructureNode(((ITextSelection) selection).getOffset()));
+ }
- return new DefaultJpaSelection(selectedNode);
+ protected JpaSelection buildSelection(JpaStructureNode selectedNode) {
+ return (selectedNode == null) ? JpaSelection.NULL_SELECTION : new DefaultJpaSelection(selectedNode);
}
-
- private IWorkbenchPage getActivePage() {
- return textEditor.getEditorSite().getWorkbenchWindow().getActivePage();
+
+ protected IWorkbenchPage getActivePage() {
+ return this.textEditor.getEditorSite().getWorkbenchWindow().getActivePage();
}
- private IWorkbenchPart getActivePart() {
+ protected IWorkbenchPart getActivePart() {
IWorkbenchPage activePage = getActivePage();
return (activePage == null) ? null: activePage.getActivePart();
}
- private IEditorPart getActiveEditor() {
+ protected IEditorPart getActiveEditor() {
IWorkbenchPage activePage = getActivePage();
return (activePage == null) ? null: activePage.getActiveEditor();
}
- private ITextEditor getActiveTextEditor() {
+ protected ITextEditor getActiveTextEditor() {
return getTextEditor(getActiveEditor());
}
- private ITextEditor getTextEditor(IWorkbenchPart part) {
+ protected ITextEditor getTextEditor(IWorkbenchPart part) {
return (part == null) ? null : (ITextEditor) part.getAdapter(ITextEditor.class);
}
- private JpaFile jpaFile() {
+ protected JpaFile getJpaFile() {
IEditorInput input = this.textEditor.getEditorInput();
if ( ! (input instanceof IFileEditorInput)) {
return null;
@@ -141,38 +144,30 @@ public class TextEditorSelectionParticipant
return JptCorePlugin.getJpaFile(((IFileEditorInput) input).getFile());
}
- private IPostSelectionProvider postSelectionProvider() {
+ protected IPostSelectionProvider getPostSelectionProvider() {
return (IPostSelectionProvider) this.textEditor.getSelectionProvider();
}
// ********** listener callbacks **********
- void editorInputChanged() {
- JpaSelection newSelection = this.calculateSelection();
- if (newSelection.equals(this.currentSelection)) {
- return;
- }
- this.currentSelection = newSelection;
-
- if (this.forwardSelection) {
- this.selectionManager.select(newSelection, this);
- }
+ protected void editorInputChanged() {
+ this.selectionChanged();
}
- void editorSelectionChanged(SelectionChangedEvent event) {
+ protected void editorSelectionChanged(SelectionChangedEvent event) {
// This is a bit kludgey. We check to see if the selection event
// occurred when a participating part is active (and so, ostensibly,
// *because* of the participating part). If so, we reselect the valid
// text.
IWorkbenchPart activePart = getActivePart();
- if (getTextEditor(activePart) != textEditor && selectionManager.isRegistered(activePart)) {
- if (currentSelection.isEmpty()) {
+ if (getTextEditor(activePart) != this.textEditor && this.selectionManager.isRegistered(activePart)) {
+ if (this.currentSelection.isEmpty()) {
return;
}
this.forwardSelection = false;
- TextRange textRange = currentSelection.getSelectedNode().getSelectionTextRange();
+ TextRange textRange = this.currentSelection.getSelectedNode().getSelectionTextRange();
if (textRange != null) {
this.textEditor.selectAndReveal(textRange.getOffset(), textRange.getLength());
}
@@ -181,12 +176,16 @@ public class TextEditorSelectionParticipant
return;
}
+ this.selectionChanged();
+ }
+
+ protected void selectionChanged() {
JpaSelection newSelection = this.calculateSelection();
if (newSelection.equals(this.currentSelection)) {
return;
}
this.currentSelection = newSelection;
-
+
if (this.forwardSelection) {
this.selectionManager.select(newSelection, this);
}
@@ -195,8 +194,8 @@ public class TextEditorSelectionParticipant
// ********** listeners **********
- private class EditorInputListener implements IPropertyListener {
- EditorInputListener() {
+ protected class EditorInputListener implements IPropertyListener {
+ protected EditorInputListener() {
super();
}
public void propertyChanged(Object source, int propId) {
@@ -208,8 +207,8 @@ public class TextEditorSelectionParticipant
}
- private class EditorSelectionListener implements ISelectionChangedListener {
- EditorSelectionListener() {
+ protected class EditorSelectionListener implements ISelectionChangedListener {
+ protected EditorSelectionListener() {
super();
}
public void selectionChanged(SelectionChangedEvent event) {
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/CommandExecutorProvider.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/CommandExecutorProvider.java
index 03b62531e4..ea1f5c68ea 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/CommandExecutorProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/CommandExecutorProvider.java
@@ -27,4 +27,27 @@ public interface CommandExecutorProvider {
*/
CommandExecutor getCommandExecutor();
+
+ /**
+ * Straightforward implementation of the command executor provider
+ * interface the returns the default command executor.
+ */
+ final class Default implements CommandExecutorProvider {
+ public static final CommandExecutorProvider INSTANCE = new Default();
+ public static CommandExecutorProvider instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private Default() {
+ super();
+ }
+ public CommandExecutor getCommandExecutor() {
+ return CommandExecutor.Default.instance();
+ }
+ @Override
+ public String toString() {
+ return "CommandExecutorProvider.Default";
+ }
+ }
+
}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/MethodSignature.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/MethodSignature.java
new file mode 100644
index 0000000000..08fcbc21d3
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/MethodSignature.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 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.utility;
+
+import java.io.PrintWriter;
+
+/**
+ * This interface describes a Java method signature; i.e. its "name"
+ * and its "parameter types". The parameter types are referenced by name,
+ * allowing us to reference classes that are not (or cannot be) loaded.
+ *
+ * Provisional API: This interface is part of an interim API that is still
+ * under development and expected to change significantly before reaching
+ * stability. It is available at this early stage to solicit feedback from
+ * pioneering adopters on the understanding that any code that uses this API
+ * will almost certainly be broken (repeatedly) as the API evolves.
+ *
+ * This interface is not intended to be implemented by clients.
+ */
+public interface MethodSignature
+ extends Comparable<MethodSignature>
+{
+
+ /**
+ * Return the method's name.
+ */
+ String getName();
+
+ /**
+ * Return the method's parameter types.
+ */
+ JavaType[] getParameterTypes();
+
+ boolean equals(String otherName, JavaType[] otherParameterTypes);
+
+ boolean equals(MethodSignature other);
+
+ /**
+ * Return a string representation of the method signature:
+ * "foo(int, java.lang.String)"
+ */
+ String getSignature();
+
+ /**
+ * Append a string representation of the method signature:
+ * "foo(int, java.lang.String)"
+ */
+ void appendSignatureTo(StringBuilder sb);
+
+ /**
+ * Print a string representation of the method signature:
+ * "foo(int, java.lang.String)"
+ */
+ void printSignatureOn(PrintWriter pw);
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleJavaType.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleJavaType.java
index faa3177b91..3ec253f142 100644
--- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleJavaType.java
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleJavaType.java
@@ -144,7 +144,7 @@ public final class SimpleJavaType
@Override
public boolean equals(Object o) {
- return (o instanceof JavaType) ? this.equals((JavaType) o) : false;
+ return (this == o) ? true : (o instanceof JavaType) ? this.equals((JavaType) o) : false;
}
@Override
@@ -217,6 +217,9 @@ public final class SimpleJavaType
return sb.toString();
}
+
+ // ********** cloning **********
+
@Override
public Object clone() {
try {
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleMethodSignature.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleMethodSignature.java
new file mode 100644
index 0000000000..48c5481c47
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/SimpleMethodSignature.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 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.utility.internal;
+
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.text.Collator;
+import java.util.Arrays;
+
+import org.eclipse.jpt.utility.JavaType;
+import org.eclipse.jpt.utility.MethodSignature;
+
+/**
+ * Straightforward implementation of the MethodSignature interface.
+ */
+public final class SimpleMethodSignature
+ implements MethodSignature, Cloneable, Serializable
+{
+ private final String name;
+
+ /**
+ * store the parameter types as names, so we can reference classes
+ * that are not loaded
+ */
+ private final JavaType[] parameterTypes;
+
+ private static final long serialVersionUID = 1L;
+
+ public static final JavaType[] EMPTY_PARAMETER_TYPES = new JavaType[0];
+
+
+ // ********** constructors **********
+
+ /**
+ * Construct a method signature with the specified name and
+ * no parameter types.
+ */
+ public SimpleMethodSignature(String name) {
+ this(name, EMPTY_PARAMETER_TYPES);
+ }
+
+ /**
+ * Construct a method signature with the specified name and parameter
+ * types.
+ */
+ public SimpleMethodSignature(String name, JavaType... parameterTypes) {
+ super();
+ if ((name == null) || (name.length() == 0)) {
+ throw new IllegalArgumentException("The name is required.");
+ }
+ if (parameterTypes == null) {
+ throw new IllegalArgumentException("The parameter types are required.");
+ }
+ checkParameterTypes(parameterTypes);
+ this.name = name;
+ this.parameterTypes = parameterTypes;
+ }
+
+ private static void checkParameterTypes(JavaType[] parameterTypes) {
+ for (int i = 0; i < parameterTypes.length; i++) {
+ if (parameterTypes[i] == null) {
+ throw new IllegalArgumentException("Missing parameter type: " + i);
+ }
+ if (parameterTypes[i].getElementTypeName().equals(void.class.getName())) {
+ throw new IllegalArgumentException("A parameter type of 'void' is not allowed: " + i);
+ }
+ }
+ }
+
+ /**
+ * Construct a method signature with the specified name and parameter
+ * types.
+ */
+ public SimpleMethodSignature(String name, String... parameterTypeNames) {
+ this(name, buildParameterTypes(parameterTypeNames));
+ }
+
+ private static JavaType[] buildParameterTypes(String[] parameterTypeNames) {
+ if (parameterTypeNames == null) {
+ throw new IllegalArgumentException("The parameter type names are required.");
+ }
+ JavaType[] parameterTypes = new JavaType[parameterTypeNames.length];
+ for (int i = 0; i < parameterTypeNames.length; i++) {
+ if (parameterTypeNames[i] == null) {
+ throw new IllegalArgumentException("Missing parameter type name: " + i);
+ }
+ parameterTypes[i] = new SimpleJavaType(parameterTypeNames[i]);
+ }
+ return parameterTypes;
+ }
+
+ /**
+ * Construct a method signature with the specified name and parameter
+ * types.
+ */
+ public SimpleMethodSignature(String name, Class<?>... parameterJavaClasses) {
+ this(name, buildParameterTypeNames(parameterJavaClasses));
+ }
+
+ private static String[] buildParameterTypeNames(Class<?>[] parameterJavaClasses) {
+ if (parameterJavaClasses == null) {
+ throw new IllegalArgumentException("The parameter Java classes are required.");
+ }
+ String[] parameterTypeNames = new String[parameterJavaClasses.length];
+ for (int i = 0; i < parameterJavaClasses.length; i++) {
+ if (parameterJavaClasses[i] == null) {
+ throw new IllegalArgumentException("Missing parameter Java class: " + i);
+ }
+ parameterTypeNames[i] = parameterJavaClasses[i].getName();
+ }
+ return parameterTypeNames;
+ }
+
+ /**
+ * Construct a method signature for the specified Java method.
+ */
+ public SimpleMethodSignature(Method method) {
+ this(method.getName(), method.getParameterTypes());
+ }
+
+
+ // ********** accessors **********
+
+ public String getName() {
+ return this.name;
+ }
+
+ public JavaType[] getParameterTypes() {
+ return this.parameterTypes;
+ }
+
+
+ // ********** comparison **********
+
+ public boolean equals(String otherName, JavaType[] otherParameterTypes) {
+ return this.name.equals(otherName)
+ && Arrays.equals(this.parameterTypes, otherParameterTypes);
+ }
+
+ public boolean equals(MethodSignature other) {
+ return this.equals(other.getName(), other.getParameterTypes());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return (this == o) ? true : (o instanceof MethodSignature) ? this.equals((MethodSignature) o) : false;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.name.hashCode() ^ Arrays.hashCode(this.parameterTypes);
+ }
+
+ public int compareTo(MethodSignature ms) {
+ int compare = Collator.getInstance().compare(this.name, ms.getName());
+ return (compare != 0) ? compare : this.compareParameterTypes(ms.getParameterTypes());
+ }
+
+ private int compareParameterTypes(JavaType[] otherParameterTypes) {
+ int len1 = this.parameterTypes.length;
+ int len2 = otherParameterTypes.length;
+ int min = Math.min(len1, len2);
+ for (int i = 0; i < min; i++) {
+ int compare = this.parameterTypes[i].compareTo(otherParameterTypes[i]);
+ if (compare != 0) {
+ return compare;
+ }
+ }
+ return (len1 == len2) ? 0 : (len1 < len2) ? -1 : 1;
+ }
+
+
+ // ********** printing and displaying **********
+
+ public String getSignature() {
+ StringBuilder sb = new StringBuilder(200);
+ this.appendSignatureTo(sb);
+ return sb.toString();
+ }
+
+ public void appendSignatureTo(StringBuilder sb) {
+ sb.append(this.name);
+ sb.append('(');
+ for (int i = 0; i < this.parameterTypes.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ this.parameterTypes[i].appendDeclarationTo(sb);
+ }
+ sb.append(')');
+ }
+
+ public void printSignatureOn(PrintWriter pw) {
+ pw.print(this.name);
+ pw.print('(');
+ for (int i = 0; i < this.parameterTypes.length; i++) {
+ if (i != 0) {
+ pw.print(", ");
+ }
+ this.parameterTypes[i].printDeclarationOn(pw);
+ }
+ pw.print(')');
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(200);
+ sb.append(ClassTools.shortClassNameForObject(this));
+ sb.append('(');
+ this.appendSignatureTo(sb);
+ sb.append(')');
+ return sb.toString();
+ }
+
+
+ // ********** cloning **********
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/resource/ClassTools.java b/jpa/tests/org.eclipse.jpt.utility.tests/resource/ClassTools.java
new file mode 100644
index 0000000000..aac17b6044
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/resource/ClassTools.java
@@ -0,0 +1,1680 @@
+/*******************************************************************************
+ * 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 test;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.Stack;
+
+/**
+ * Convenience methods related to the java.lang.reflect package.
+ * These methods provide shortcuts for manipulating objects via
+ * reflection; particularly when dealing with fields and/or methods that
+ * are not publicly accessible or are inherited.
+ *
+ * In most cases, all the exceptions are handled and
+ * wrapped in java.lang.RuntimeExceptions; so these methods should
+ * be used when you are confident that you will not having any problems
+ * using reflection.
+ *
+ * There are also a number of methods whose names
+ * begin with "attempt". These methods will throw a NoSuchMethodException
+ * or NoSuchFieldException when appropriate, allowing you to probe
+ * for methods that should be present but might not.
+ */
+public final class ClassTools {
+
+ public static final Class<?>[] ZERO_PARAMETER_TYPES = new Class[0];
+ public static final Object[] ZERO_PARAMETERS = new Object[0];
+ private static final String CR = StringTools.CR;
+
+ public static final char NESTED_CLASS_NAME_SEPARATOR = '$';
+
+ public static final char ARRAY_INDICATOR = '[';
+ public static final char TYPE_DECLARATION_ARRAY_OPEN = '[';
+ public static final char TYPE_DECLARATION_ARRAY_CLOSE = ']';
+
+ public static final char REFERENCE_CLASS_CODE = 'L';
+ public static final char REFERENCE_CLASS_NAME_DELIMITER = ';';
+
+ private static Primitive[] PRIMITIVES; // pseudo-'final' - lazy-initialized
+ public static final char BYTE_CODE = 'B';
+ public static final char CHAR_CODE = 'C';
+ public static final char DOUBLE_CODE = 'D';
+ public static final char FLOAT_CODE = 'F';
+ public static final char INT_CODE = 'I';
+ public static final char LONG_CODE = 'J';
+ public static final char SHORT_CODE = 'S';
+ public static final char BOOLEAN_CODE = 'Z';
+ public static final char VOID_CODE = 'V';
+ private static int MAX_PRIMITIVE_CLASS_NAME_LENGTH = -1; // pseudo-'final' - lazy-initialized
+ private static int MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = -1; // pseudo-'final' - lazy-initialized
+
+ public static final String VOID_CLASS_NAME = void.class.getName();
+ public static final String VOID_WRAPPER_CLASS_NAME = java.lang.Void.class.getName();
+
+
+ /**
+ * Return all the fields for the
+ * specified class, including inherited fields.
+ * Class#allFields()
+ */
+ @Deprecated
+ public static Field[] allFields(Class<?> javaClass) {
+ Stack<Field> stack = new Stack<Field>();
+ for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
+ pushDeclaredFields(tempClass, stack);
+ }
+ Collections.reverse(stack);
+ return stack.toArray(new Field[stack.size()]);
+ }
+
+ /**
+ * Return all the methods for the
+ * specified class, including inherited methods.
+ * Class#allMethods()
+ */
+ public static Method[] allMethods(Class<?> javaClass) {
+ Stack<Method> stack = new Stack<Method>();
+ for (Class<?> tempClass = javaClass; tempClass != null; tempClass = tempClass.getSuperclass()) {
+ pushDeclaredMethods(tempClass, stack);
+ }
+ Collections.reverse(stack);
+ return stack.toArray(new Method[stack.size()]);
+ }
+
+ /**
+ * Convenience method.
+ * Return a new instance of the specified class,
+ * using the class's default (zero-argument) constructor.
+ * Throw an exception if the default constructor is not defined.
+ * Class#newInstance() throws NoSuchMethodException
+ */
+ @Deprecated
+ public static <T> T attemptNewInstance(Class<T> javaClass) throws NoSuchMethodException {
+ return attemptNewInstance(javaClass, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
+ }
+
+ /**
+ * Return a new instance of the specified class,
+ * given the constructor parameter types and parameters.
+ * Throw an exception if the constructor is not defined.
+ * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException
+ */
+ public static <T> T attemptNewInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException {
+ try {
+ return constructor(javaClass, parameterTypes).newInstance(parameters);
+ } catch (InstantiationException ie) {
+ throw new RuntimeException(ie + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), ie);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), iae);
+ } catch (InvocationTargetException ite) {
+ throw new RuntimeException(fullyQualifiedConstructorSignature(javaClass, parameterTypes) + CR + ite.getTargetException(), ite);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Return a new instance of the specified class,
+ * given the constructor parameter type and parameter.
+ * Throw an exception if the constructor is not defined.
+ * Class#newInstance(Class<?> parameterType, Object parameter) throws NoSuchMethodException
+ */
+ public static <T> T attemptNewInstance(Class<T> javaClass, Class<?> parameterType, Object parameter) throws NoSuchMethodException {
+ return attemptNewInstance(javaClass, new Class[] {parameterType}, new Object[] {parameter});
+ }
+
+ /**
+ * Attempt to get a field value, given the containing object and field name.
+ * Return its result.
+ * Useful for accessing private, package, or protected fields.
+ * Throw an exception if the field is not defined.
+ * Object#getFieldValue(String fieldName) throws NoSuchFieldException
+ */
+ public static Object attemptToGetFieldValue(Object object, String fieldName) throws NoSuchFieldException {
+ try {
+ return field(object, fieldName).get(object);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae + CR + fullyQualifiedFieldName(object, fieldName), iae);
+ }
+ }
+
+ /**
+ * Attempt to get a static field value, given the containing object and field name.
+ * Return its result.
+ * Useful for accessing private, package, or protected fields.
+ * Throw an exception if the field is not defined.
+ * Class#getStaticFieldValue(String fieldName) throws NoSuchFieldException
+ */
+ public static Object attemptToGetStaticFieldValue(Class<?> javaClass, String fieldName) throws NoSuchFieldException {
+ try {
+ return field(javaClass, fieldName).get(null);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae + CR + fullyQualifiedFieldName(javaClass, fieldName), iae);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Attempt to execute a zero-argument method,
+ * given the receiver and method name.
+ * Return its result.
+ * Throw an exception if the method is not found.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName) throws NoSuchMethodException
+ */
+ public static Object attemptToExecuteMethod(Object receiver, String methodName) throws NoSuchMethodException {
+ return attemptToExecuteMethod(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
+ }
+
+ /**
+ * Convenience method.
+ * Attempt to execute a method, given the receiver,
+ * method name, parameter type, and parameter.
+ * Return its result.
+ * Throw an exception if the method is not found.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException
+ */
+ public static Object attemptToExecuteMethod(Object receiver, String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException {
+ return attemptToExecuteMethod(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter});
+ }
+
+ /**
+ * Attempt to execute a method, given the receiver,
+ * method name, parameter types, and parameters.
+ * Return its result.
+ * Throw an exception if the method is not found.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException
+ */
+ public static Object attemptToExecuteMethod(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException {
+ return executeMethod(method(receiver, methodName, parameterTypes), receiver, parameters);
+ }
+
+ /**
+ * Attempt to execute a method, given the receiver,
+ * method name, parameter types, and parameters.
+ * Return its result.
+ * Throw an exception if the method is not found.
+ * If the executed method throws an exception, rethrow that exception.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException
+ */
+ public static Object attemptToExecuteMethodWithException(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters)
+ throws Throwable, NoSuchMethodException
+ {
+ return executeMethodWithException(method(receiver, methodName, parameterTypes), receiver, parameters);
+ }
+
+ /**
+ * Convenience method.
+ * Attempt to execute a zero-argument static method,
+ * given the class and method name.
+ * Return its result.
+ * Throw an exception if the method is not found.
+ * Useful for invoking private, package, or protected methods.
+ * Class#executeStaticMethod(String methodName) throws NoSuchMethodException
+ */
+ public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName) throws NoSuchMethodException {
+ return attemptToExecuteStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
+ }
+
+ /**
+ * Attempt to execute a static method, given the class,
+ * method name, parameter types, and parameters.
+ * Return its result.
+ * Throw an exception if the method is not found.
+ * Useful for invoking private, package, or protected methods.
+ * Class#executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException
+ */
+ public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] parameters) throws NoSuchMethodException {
+ return executeStaticMethod(staticMethod(javaClass, methodName, parameterTypes), parameters);
+ }
+
+ /**
+ * Convenience method.
+ * Attempt to execute a static method, given the class,
+ * method name, parameter type, and parameter.
+ * Return its result.
+ * Throw an exception if the method is not found.
+ * Useful for invoking private, package, or protected methods.
+ * Class#executeStaticMethod(String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException
+ */
+ public static Object attemptToExecuteStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterType, Object parameter) throws NoSuchMethodException {
+ return attemptToExecuteStaticMethod(javaClass, methodName, new Class[] {parameterType}, new Object[] {parameter});
+ }
+
+ /**
+ * Attempt to set a field value, given the
+ * containing object, field name, and new field value.
+ * Useful for accessing private, package, or protected fields.
+ * Throw an exception if the field is not defined.
+ * Object#setFieldValue(String fieldName, Object fieldValue) throws NoSuchFieldException
+ */
+ public static void attemptToSetFieldValue(Object object, String fieldName, Object fieldValue) throws NoSuchFieldException {
+ try {
+ field(object, fieldName).set(object, fieldValue);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae + CR + fullyQualifiedFieldName(object, fieldName), iae);
+ }
+ }
+
+ /**
+ * Attempt to set a static field value, given the
+ * containing class, field name, and new field value.
+ * Useful for accessing private, package, or protected fields.
+ * Throw an exception if the field is not defined.
+ * Class#setStaticFieldValue(String fieldName, Object fieldValue) throws NoSuchFieldException
+ */
+ public static void attemptToSetStaticFieldValue(Class<?> javaClass, String fieldName, Object fieldValue) throws NoSuchFieldException {
+ try {
+ field(javaClass, fieldName).set(null, fieldValue);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae + CR + fullyQualifiedFieldName(javaClass, fieldName), iae);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Return the default (zero-argument) constructor
+ * for the specified class.
+ * Set accessible to true, so we can access
+ * private/package/protected constructors.
+ * Class#constructor() throws NoSuchMethodException
+ */
+ public static <T> Constructor<T> constructor(Class<T> javaClass) throws NoSuchMethodException {
+ return constructor(javaClass, ZERO_PARAMETER_TYPES);
+ }
+
+ /**
+ * Return the constructor for the specified class
+ * and formal parameter types.
+ * Set accessible to true, so we can access
+ * private/package/protected constructors.
+ * Class#constructor(Class<?>[] parameterTypes) throws NoSuchMethodException
+ */
+ public static <T> Constructor<T> constructor(Class<T> javaClass, Class<?>[] parameterTypes) throws NoSuchMethodException {
+ Constructor<T> constructor = javaClass.getDeclaredConstructor(parameterTypes);
+ constructor.setAccessible(true);
+ return constructor;
+ }
+
+ /**
+ * Convenience method.
+ * Return the constructor for the specified class
+ * and formal parameter type.
+ * Set accessible to true, so we can access
+ * private/package/protected constructors.
+ * Class#constructor(Class<?> parameterType) throws NoSuchMethodException
+ */
+ public static <T> Constructor<T> constructor(Class<T> javaClass, Class<?> parameterType) throws NoSuchMethodException {
+ return constructor(javaClass, new Class[] {parameterType});
+ }
+
+ /**
+ * Return the declared fields for the specified class.
+ * Set accessible to true, so we can access
+ * private/package/protected fields.
+ * Class#accessibleDeclaredFields()
+ */
+ public static Field[] declaredFields(Class<?> javaClass) {
+ Field[] fields = javaClass.getDeclaredFields();
+ for (Field field : fields) {
+ field.setAccessible(true);
+ }
+ return fields;
+ }
+
+ /**
+ * Return the declared methods for the
+ * specified class.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ * Class#accessibleDeclaredMethods()
+ */
+ public static Method[] declaredMethods(Class<?> javaClass) {
+ Method[] methods = javaClass.getDeclaredMethods();
+ for (Method method : methods) {
+ method.setAccessible(true);
+ }
+ return methods;
+ }
+
+ /**
+ * Return the default (zero-argument) constructor
+ * for the specified class.
+ * Set accessible to true, so we can access
+ * private/package/protected constructors.
+ * Class#defaultConstructor()
+ */
+ public static <T> Constructor<T> defaultConstructor(Class<T> javaClass) throws NoSuchMethodException {
+ return constructor(javaClass);
+ }
+
+ /**
+ * Return a field for the specified class and field name.
+ * If the class does not directly
+ * define the field, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected fields.
+ */
+ public static Field field(Class<?> javaClass, String fieldName) throws NoSuchFieldException {
+ Field field = null;
+ try {
+ field = javaClass.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException ex) {
+ Class<?> superclass = javaClass.getSuperclass();
+ if (superclass == null) {
+ throw ex;
+ }
+ // recurse
+ return field(superclass, fieldName);
+ }
+ field.setAccessible(true);
+ return field;
+ }
+
+ /**
+ * Convenience method.
+ * Return a field for the specified object and field name.
+ * If the object's class does not directly
+ * define the field, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected fields.
+ */
+ public static Field field(Object object, String fieldName) throws NoSuchFieldException {
+ return field(object.getClass(), fieldName);
+ }
+
+ /*
+ * Return a string representation of the specified constructor.
+ */
+ private static String fullyQualifiedConstructorSignature(Class<?> javaClass, Class<?>[] parameterTypes) {
+ return fullyQualifiedMethodSignature(javaClass, null, parameterTypes);
+ }
+
+ /*
+ * Return a string representation of the specified field.
+ */
+ private static String fullyQualifiedFieldName(Class<?> javaClass, String fieldName) {
+ StringBuilder sb = new StringBuilder(200);
+ sb.append(javaClass.getName());
+ sb.append('.');
+ sb.append(fieldName);
+ return sb.toString();
+ }
+
+ /*
+ * Return a string representation of the specified field.
+ */
+ private static String fullyQualifiedFieldName(Object object, String fieldName) {
+ return fullyQualifiedFieldName(object.getClass(), fieldName);
+ }
+
+ /*
+ * Return a string representation of the specified method.
+ */
+ private static String fullyQualifiedMethodSignature(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) {
+ StringBuilder sb = new StringBuilder(200);
+ sb.append(javaClass.getName());
+ // this check allows us to use this code for constructors, where the methodName is null
+ if (methodName != null) {
+ sb.append('.');
+ sb.append(methodName);
+ }
+ sb.append('(');
+ int max = parameterTypes.length - 1;
+ if (max != -1) {
+ // stop one short of the end of the array
+ for (int i = 0; i < max; i++) {
+ sb.append(parameterTypes[i].getName());
+ sb.append(", ");
+ }
+ sb.append(parameterTypes[max].getName());
+ }
+ sb.append(')');
+ return sb.toString();
+ }
+
+ /*
+ * Return a string representation of the specified method.
+ */
+ private static String fullyQualifiedMethodSignature(Object receiver, String methodName, Class<?>[] parameterTypes) {
+ return fullyQualifiedMethodSignature(receiver.getClass(), methodName, parameterTypes);
+ }
+
+ /**
+ * Get a field value, given the containing object and field name.
+ * Return its result.
+ * Useful for accessing private, package, or protected fields.
+ * Object#getFieldValue(String fieldName)
+ */
+ public static Object fieldValue(Object object, String fieldName) {
+ try {
+ return attemptToGetFieldValue(object, fieldName);
+ } catch (NoSuchFieldException nsfe) {
+ throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(object, fieldName), nsfe);
+ }
+ }
+
+ /**
+ * Get a static field value, given the containing class and field name.
+ * Return its result.
+ * Useful for accessing private, package, or protected fields.
+ * Class#getStaticFieldValue(String fieldName)
+ */
+ public static Object staticFieldValue(Class<?> javaClass, String fieldName) {
+ try {
+ return attemptToGetStaticFieldValue(javaClass, fieldName);
+ } catch (NoSuchFieldException nsfe) {
+ throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(javaClass, fieldName), nsfe);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Execute a zero-argument method, given the receiver and method name.
+ * Return its result.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName)
+ */
+ public static Object executeMethod(Object receiver, String methodName) {
+ return executeMethod(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
+ }
+
+ /**
+ * Execute a method, given the receiver,
+ * method name, parameter types, and parameters.
+ * Return its result.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters)
+ */
+ public static Object executeMethod(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters) {
+ try {
+ return attemptToExecuteMethod(receiver, methodName, parameterTypes, parameters);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(receiver, methodName, parameterTypes), nsme);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Execute a one-argument method, given the receiver,
+ * method name, parameter type, and parameter.
+ * Return its result.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName, Class<?> parameterType, Object parameter)
+ */
+ public static Object executeMethod(Object receiver, String methodName, Class<?> parameterType, Object parameter) {
+ return executeMethod(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter});
+ }
+
+ /**
+ * Convenience method.
+ * Execute a zero-argument method, given the receiver and method name.
+ * Return its result.
+ * If the method throws an exception, rethrow that exception.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName)
+ */
+ public static Object executeMethodWithException(Object receiver, String methodName)
+ throws Throwable
+ {
+ return executeMethodWithException(receiver, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
+ }
+
+ /**
+ * Convenience method.
+ * Execute a one-argument method, given the receiver,
+ * method name, parameter type, and parameter.
+ * Return its result.
+ * If the method throws an exception, rethrow that exception.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName, Class<?> parameterType, Object parameter)
+ */
+ public static Object executeMethodWithException(Object receiver, String methodName, Class<?> parameterType, Object parameter)
+ throws Throwable
+ {
+ return executeMethodWithException(receiver, methodName, new Class[] {parameterType}, new Object[] {parameter});
+ }
+
+ /**
+ * Execute a method, given the receiver,
+ * method name, parameter types, and parameters.
+ * Return its result.
+ * If the method throws an exception, rethrow that exception.
+ * Useful for invoking private, package, or protected methods.
+ * Object#execute(String methodName, Class<?>[] parameterTypes, Object[] parameters)
+ */
+ public static Object executeMethodWithException(Object receiver, String methodName, Class<?>[] parameterTypes, Object[] parameters)
+ throws Throwable
+ {
+ try {
+ return attemptToExecuteMethodWithException(receiver, methodName, parameterTypes, parameters);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(receiver, methodName, parameterTypes), nsme);
+ }
+ }
+
+ /**
+ * Execute the specified method with the specified parameters.
+ * Return its result.
+ * Convert exceptions to RuntimeExceptions.
+ */
+ public static Object executeMethod(Method method, Object receiver, Object[] parameters) {
+ try {
+ return method.invoke(receiver, parameters);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae + CR + method, iae);
+ } catch (InvocationTargetException ite) {
+ throw new RuntimeException(method + CR + ite.getTargetException(), ite);
+ }
+ }
+
+ /**
+ * Execute the specified method with the specified parameters.
+ * Return its result.
+ * If the method throws an exception, rethrow that exception.
+ * Convert all other exceptions to RuntimeExceptions.
+ */
+ public static Object executeMethodWithException(Method method, Object receiver, Object[] parameters)
+ throws Throwable
+ {
+ try {
+ return method.invoke(receiver, parameters);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae + CR + method, iae);
+ } catch (InvocationTargetException ite) {
+ Throwable cause = ite.getCause();
+ if (cause == null) {
+ throw new RuntimeException(method.toString(), ite);
+ }
+ throw cause;
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Execute a zero-argument static method,
+ * given the class and method name.
+ * Return its result.
+ * Useful for invoking private, package, or protected methods.
+ * Class#executeStaticMethod(String methodName)
+ */
+ public static Object executeStaticMethod(Class<?> javaClass, String methodName) {
+ return executeStaticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
+ }
+
+ /**
+ * Execute a static method, given the class,
+ * method name, parameter types, and parameters.
+ * Return its result.
+ * Useful for invoking private, package, or protected methods.
+ * Class#executeStaticMethod(String methodName, Class<?>[] parameterTypes, Object[] parameters)
+ */
+ public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes, Object[] parameters) {
+ try {
+ return attemptToExecuteStaticMethod(javaClass, methodName, parameterTypes, parameters);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme + CR + fullyQualifiedMethodSignature(javaClass, methodName, parameterTypes), nsme);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Execute a static method, given the class,
+ * method name, parameter type, and parameter.
+ * Return its result.
+ * Useful for invoking private, package, or protected methods.
+ * Class#executeStaticMethod(String methodName, Class<?> parameterType, Object parameter)
+ */
+ public static Object executeStaticMethod(Class<?> javaClass, String methodName, Class<?> parameterType, Object parameter) {
+ return executeStaticMethod(javaClass, methodName, new Class[] {parameterType}, new Object[] {parameter});
+ }
+
+ /**
+ * Execute the specified static method with the specified parameters.
+ * Return its result.
+ * Convert exceptions to RuntimeExceptions.
+ */
+ public static Object executeStaticMethod(Method method, Object[] parameters) {
+ return executeMethod(method, null, parameters);
+ }
+
+ /**
+ * Convenience method.
+ * Return a zero-argument method for the specified class
+ * and method name. If the class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method method(Class<?> javaClass, String methodName) throws NoSuchMethodException {
+ return method(javaClass, methodName, ZERO_PARAMETER_TYPES);
+ }
+
+ /**
+ * Return a method for the specified class, method name,
+ * and formal parameter types. If the class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method method(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException {
+ Method method = null;
+ try {
+ method = javaClass.getDeclaredMethod(methodName, parameterTypes);
+ } catch (NoSuchMethodException ex) {
+ Class<?> superclass = javaClass.getSuperclass();
+ if (superclass == null) {
+ throw ex;
+ }
+ // recurse
+ return method(superclass, methodName, parameterTypes);
+ }
+ method.setAccessible(true);
+ return method;
+ }
+
+ /**
+ * Convenience method.
+ * Return a method for the specified class, method name,
+ * and formal parameter type. If the class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method method(Class<?> javaClass, String methodName, Class<?> parameterType) throws NoSuchMethodException {
+ return method(javaClass, methodName, new Class[] {parameterType});
+ }
+
+ /**
+ * Convenience method.
+ * Return a zero-argument method for the specified object
+ * and method name. If the object's class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method method(Object object, String methodName) throws NoSuchMethodException {
+ return method(object.getClass(), methodName);
+ }
+
+ /**
+ * Convenience method.
+ * Return a method for the specified object, method name,
+ * and formal parameter types. If the object's class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method method(Object object, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException {
+ return method(object.getClass(), methodName, parameterTypes);
+ }
+
+ /**
+ * Convenience method.
+ * Return a method for the specified object, method name,
+ * and formal parameter type. If the object's class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method method(Object object, String methodName, Class<?> parameterType) throws NoSuchMethodException {
+ return method(object.getClass(), methodName, parameterType);
+ }
+
+ /**
+ * Convenience method.
+ * Return the specified class (without the checked exception).
+ */
+ public static Class<?> classForName(String className) {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException ex) {
+ throw new RuntimeException(className, ex);
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Return a new instance of the specified class,
+ * using the class's default (zero-argument) constructor.
+ * Class#newInstance()
+ */
+ public static <T> T newInstance(Class<T> javaClass) {
+ return newInstance(javaClass, ZERO_PARAMETER_TYPES, ZERO_PARAMETERS);
+ }
+
+ /**
+ * Convenience method.
+ * Return a new instance of the specified class,
+ * using the class's default (zero-argument) constructor.
+ * Class#newInstance()
+ */
+ public static Object newInstance(String className) throws ClassNotFoundException {
+ return newInstance(className, null);
+ }
+
+ /**
+ * Convenience method.
+ * Return a new instance of the specified class,
+ * using the class's default (zero-argument) constructor.
+ * Class#newInstance()
+ */
+ public static Object newInstance(String className, ClassLoader classLoader) throws ClassNotFoundException {
+ return newInstance(Class.forName(className, true, classLoader));
+ }
+
+ /**
+ * Return a new instance of the specified class,
+ * given the constructor parameter types and parameters.
+ * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters)
+ */
+ public static <T> T newInstance(Class<T> javaClass, Class<?>[] parameterTypes, Object[] parameters) {
+ try {
+ return attemptNewInstance(javaClass, parameterTypes, parameters);
+ } catch (NoSuchMethodException nsme) {
+ throw new RuntimeException(nsme + CR + fullyQualifiedConstructorSignature(javaClass, parameterTypes), nsme);
+ }
+ }
+
+ /**
+ * Return a new instance of the specified class,
+ * given the constructor parameter types and parameters.
+ * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters)
+ */
+ public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] parameters) throws ClassNotFoundException {
+ return newInstance(className, parameterTypes, parameters, null);
+ }
+
+ /**
+ * Return a new instance of the specified class,
+ * given the constructor parameter types and parameters.
+ * Class#newInstance(Class<?>[] parameterTypes, Object[] parameters)
+ */
+ public static Object newInstance(String className, Class<?>[] parameterTypes, Object[] parameters, ClassLoader classLoader) throws ClassNotFoundException {
+ return newInstance(Class.forName(className, true, classLoader), parameterTypes, parameters);
+ }
+
+ /**
+ * Convenience method.
+ * Return a new instance of the specified class,
+ * given the constructor parameter type and parameter.
+ * Class#newInstance(Class<?> parameterType, Object parameter)
+ */
+ public static <T> T newInstance(Class<T> javaClass, Class<?> parameterType, Object parameter) {
+ return newInstance(javaClass, new Class[] {parameterType}, new Object[] {parameter});
+ }
+
+ /**
+ * Return a new instance of the specified class,
+ * given the constructor parameter type and parameter.
+ * Class#newInstance(Class<?> parameterType, Object parameter)
+ */
+ public static Object newInstance(String className, Class<?> parameterType, Object parameter) throws ClassNotFoundException {
+ return newInstance(className, parameterType, parameter, null);
+ }
+
+ /**
+ * Return a new instance of the specified class,
+ * given the constructor parameter type and parameter.
+ * Class#newInstance(Class<?> parameterType, Object parameter)
+ */
+ public static Object newInstance(String className, Class<?> parameterType, Object parameter, ClassLoader classLoader) throws ClassNotFoundException {
+ return newInstance(Class.forName(className, false, classLoader), parameterType, parameter);
+ }
+
+ /*
+ * Push the declared fields for the specified class
+ * onto the top of the stack.
+ */
+ private static void pushDeclaredFields(Class<?> javaClass, Stack<Field> stack) {
+ Field[] fields = declaredFields(javaClass);
+ for (int i = fields.length; i-- > 0; ) {
+ stack.push(fields[i]);
+ }
+ }
+
+ /*
+ * Push the declared methods for the specified class
+ * onto the top of the stack.
+ */
+ private static void pushDeclaredMethods(Class<?> javaClass, Stack<Method> stack) {
+ Method[] methods = declaredMethods(javaClass);
+ for (int i = methods.length; i-- > 0; ) {
+ stack.push(methods[i]);
+ }
+ }
+
+ /**
+ * Set a field value, given the containing object, field name, and new field value.
+ * Useful for accessing private, package, or protected fields.
+ * Object#setFieldValue(String fieldName, Object fieldValue)
+ */
+ public static void setFieldValue(Object object, String fieldName, Object fieldValue) {
+ try {
+ attemptToSetFieldValue(object, fieldName, fieldValue);
+ } catch (NoSuchFieldException nsfe) {
+ throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(object, fieldName), nsfe);
+ }
+ }
+
+ /**
+ * Set a static field value, given the containing class, field name, and new field value.
+ * Useful for accessing private, package, or protected fields.
+ * Class#setStaticFieldValue(String fieldName, Object fieldValue)
+ */
+ public static void setStaticFieldValue(Class<?> javaClass, String fieldName, Object fieldValue) {
+ try {
+ attemptToSetStaticFieldValue(javaClass, fieldName, fieldValue);
+ } catch (NoSuchFieldException nsfe) {
+ throw new RuntimeException(nsfe + CR + fullyQualifiedFieldName(javaClass, fieldName), nsfe);
+ }
+ }
+
+ /**
+ * Return the short name of the object's class.
+ * Class#getShortName()
+ */
+ public static String shortClassNameForObject(Object object) {
+ return shortNameFor(object.getClass());
+ }
+
+ /**
+ * Return the short name of the class (e.g. "Object").
+ * Class#getShortName()
+ */
+ public static String shortNameForClassNamed(String className) {
+ return className.substring(className.lastIndexOf('.') + 1);
+ }
+
+ /**
+ * Return the short name of the class (e.g. "Object").
+ * Class#getShortName()
+ */
+ public static String shortNameFor(Class<?> javaClass) {
+ return shortNameForClassNamed(javaClass.getName());
+ }
+
+ /**
+ * Return the nested name of the object's class.
+ * Class#getNestedName()
+ */
+ public static String nestedClassNameForObject(Object object) {
+ return nestedNameFor(object.getClass());
+ }
+
+ /**
+ * Return the nested name of the class (e.g. "Entry").
+ * Class#getNestedName()
+ */
+ public static String nestedNameForClassNamed(String className) {
+ return className.substring(className.lastIndexOf(NESTED_CLASS_NAME_SEPARATOR) + 1);
+ }
+
+ /**
+ * Return the nested name of the class (e.g. "Entry").
+ * Class#getNestedName()
+ */
+ public static String nestedNameFor(Class<?> javaClass) {
+ return nestedNameForClassNamed(javaClass.getName());
+ }
+
+ /**
+ * Return the "toString()" name of the object's class.
+ */
+ public static String toStringClassNameForObject(Object object) {
+ return toStringNameFor(object.getClass());
+ }
+
+ /**
+ * Return the "toString()" name of the class.
+ * "Member" classes will return only the final name:
+ * "com.foo.bar.TopLevelClass$MemberClass$NestedMemberClass"
+ * => "NestedMemberClass"
+ * "Local" and "anonymous" classes will still return the embedded '$'s:
+ * "com.foo.bar.TopLevelClass$1LocalClass"
+ * => "TopLevelClass$1LocalClass"
+ * "com.foo.bar.TopLevelClass$1"
+ * => "TopLevelClass$1"
+ */
+ public static String toStringNameForClassNamed(String className) {
+ return classNamedIsMember(className) ?
+ className.substring(className.lastIndexOf(NESTED_CLASS_NAME_SEPARATOR) + 1)
+ :
+ className.substring(className.lastIndexOf('.') + 1);
+ }
+
+ /**
+ * Return the "toString()" name of the class.
+ */
+ public static String toStringNameFor(Class<?> javaClass) {
+ return toStringNameForClassNamed(javaClass.getName());
+ }
+
+ /**
+ * Return the package name of the class (e.g. "java.lang").
+ * Class#getPackageName()
+ */
+ public static String packageNameFor(Class<?> javaClass) {
+ return packageNameForClassNamed(javaClass.getName());
+ }
+
+ /**
+ * Return the package name of the class (e.g. "java.lang").
+ * Class#getPackageName()
+ */
+ public static String packageNameForClassNamed(String className) {
+ int lastPeriod = className.lastIndexOf('.');
+ if (lastPeriod == -1) {
+ return "";
+ }
+ return className.substring(0, lastPeriod);
+ }
+
+ /**
+ * Return the short name of the class,
+ * followed by its package name (e.g. "Object (java.lang)").
+ * Class#getShortNameWithPackage()
+ */
+ public static String shortNameWithPackage(Class<?> javaClass) {
+ StringBuilder sb = new StringBuilder(200);
+ sb.append(shortNameFor(javaClass));
+ if ( ! javaClass.isPrimitive()) {
+ sb.append(" (");
+ sb.append(packageNameFor(javaClass));
+ sb.append(')');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convenience method.
+ * Return a zero-argument, static method for the specified class
+ * and method name. If the class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method staticMethod(Class<?> javaClass, String methodName) throws NoSuchMethodException {
+ return staticMethod(javaClass, methodName, ZERO_PARAMETER_TYPES);
+ }
+
+ /**
+ * Return a static method for the specified class, method name,
+ * and formal parameter types. If the class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method staticMethod(Class<?> javaClass, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException {
+ Method method = method(javaClass, methodName, parameterTypes);
+ if (Modifier.isStatic(method.getModifiers())) {
+ return method;
+ }
+ throw new NoSuchMethodException(fullyQualifiedMethodSignature(javaClass, methodName, parameterTypes));
+ }
+
+ /**
+ * Convenience method.
+ * Return a static method for the specified class, method name,
+ * and formal parameter type. If the class does not directly
+ * implement the method, look for it in the class's superclasses.
+ * Set accessible to true, so we can access
+ * private/package/protected methods.
+ */
+ public static Method staticMethod(Class<?> javaClass, String methodName, Class<?> parameterTypes) throws NoSuchMethodException {
+ return staticMethod(javaClass, methodName, new Class[] {parameterTypes});
+ }
+
+ /**
+ * Return whether the specified class can be "declared" in code;
+ * i.e. it is either a "top-level" class or a "member" class, but it
+ * is not an "array" class. This method rolls together all the checks
+ * from the other methods for a bit of a performance tweak.
+ * Class#isDeclarable()
+ */
+ public static boolean classNamedIsDeclarable(String className) {
+ if (className.charAt(0) == ARRAY_INDICATOR) {
+ return false; // it is an "array" class
+ }
+ int index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR);
+ if (index == -1) {
+ return true; // it is a "top-level" class
+ }
+ do {
+ // the character immediately after each dollar sign cannot be a digit
+ index++;
+ if (Character.isDigit(className.charAt(index))) {
+ return false;
+ }
+ index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR, index);
+ } while (index != -1);
+ return true;
+ }
+
+ /**
+ * Return whether the specified class is a "top-level" class,
+ * as opposed to a "member", "local", or "anonymous" class,
+ * using the standard jdk naming conventions (i.e. the class
+ * name does NOT contain a '$': "TopLevelClass").
+ * Class#isTopLevel()
+ */
+ public static boolean classNamedIsTopLevel(String className) {
+ if (classNamedIsArray(className)) {
+ return false;
+ }
+ return className.indexOf(NESTED_CLASS_NAME_SEPARATOR) == -1;
+ }
+
+ /**
+ * Return whether the specified class is a "member" class,
+ * as opposed to a "top-level", "local", or "anonymous" class,
+ * using the standard jdk naming conventions (i.e. the class
+ * name contains at least one '$' and all the names between
+ * each '$' are legal class names:
+ * "TopLevelClass$MemberClass$NestedMemberClass").
+ * Class#isMember()
+ */
+ public static boolean classNamedIsMember(String className) {
+ if (classNamedIsArray(className)) {
+ return false;
+ }
+ int index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR);
+ if (index == -1) {
+ return false; // it is a "top-level" class
+ }
+ do {
+ // the character immediately after each dollar sign cannot be a digit
+ index++;
+ if (Character.isDigit(className.charAt(index))) {
+ return false;
+ }
+ index = className.indexOf(NESTED_CLASS_NAME_SEPARATOR, index);
+ } while (index != -1);
+ return true;
+ }
+
+ /**
+ * Return whether the specified class is a "local" class,
+ * as opposed to a "top-level", "member", or "anonymous" class,
+ * using the standard jdk (or Eclipse) naming conventions.
+ * In the jdk, the class name ends with '$nnnXXX' where the '$' is
+ * followed by a series of numeric digits which are followed by the
+ * local class name: "TopLevelClass$1LocalClass".
+ * In Eclipse, the class name ends with '$nnn$XXX' where the '$' is
+ * followed by a series of numeric digits which are separated from
+ * the local class name by another '$': "TopLevelClass$1$LocalClass".
+ * Class#isLocal()
+ */
+ public static boolean classNamedIsLocal(String className) {
+ if (classNamedIsArray(className)) {
+ return false;
+ }
+ int dollar = className.indexOf(NESTED_CLASS_NAME_SEPARATOR);
+ if (dollar == -1) {
+ return false;
+ }
+ if ( ! Character.isDigit(className.charAt(dollar + 1))) {
+ return false;
+ }
+ int len = className.length();
+ for (int i = dollar + 2; i < len; i++) {
+ if (Character.isJavaIdentifierStart(className.charAt(i))) {
+ return true;
+ }
+ }
+ // all the characters past the $ are digits (anonymous)
+ return false;
+ }
+
+ /**
+ * Return whether the specified class is an "anonymous" class,
+ * as opposed to a "top-level", "member", or "local" class,
+ * using the standard jdk naming conventions (i.e. the class
+ * name ends with '$nnn' where all the characters past the
+ * last '$' are numeric digits: "TopLevelClass$1").
+ * Class#isAnonymous()
+ */
+ public static boolean classNamedIsAnonymous(String className) {
+ if (classNamedIsArray(className)) {
+ return false;
+ }
+ int dollar = className.indexOf(NESTED_CLASS_NAME_SEPARATOR);
+ if (dollar == -1) {
+ return false;
+ }
+ int start = dollar + 1;
+ for (int i = className.length(); i-- > start; ) {
+ if ( ! Character.isDigit(className.charAt(i))) {
+ return false;
+ }
+ }
+ // all the characters past the $ are digits
+ return true;
+ }
+
+ /**
+ * Return the "array depth" of the specified class.
+ * The depth is the number of dimensions for an array type.
+ * Non-array types have a depth of zero.
+ * Class#getArrayDepth()
+ */
+ public static int arrayDepthFor(Class<?> javaClass) {
+ int depth = 0;
+ while (javaClass.isArray()) {
+ depth++;
+ javaClass = javaClass.getComponentType();
+ }
+ return depth;
+ }
+
+ /**
+ * Return the "array depth" of the specified object.
+ * The depth is the number of dimensions for an array.
+ * Non-arrays have a depth of zero.
+ */
+ public static int arrayDepthForObject(Object object) {
+ return arrayDepthFor(object.getClass());
+ }
+
+ /**
+ * Return the "array depth" of the specified class.
+ * The depth is the number of dimensions for an array type.
+ * Non-array types have a depth of zero.
+ * @see java.lang.Class#getName()
+ * Class#getArrayDepth()
+ */
+ public static int arrayDepthForClassNamed(String className) {
+ int depth = 0;
+ while (className.charAt(depth) == ARRAY_INDICATOR) {
+ depth++;
+ }
+ return depth;
+ }
+
+ /**
+ * Return whether the specified class is an array type.
+ * @see java.lang.Class#getName()
+ */
+ public static boolean classNamedIsArray(String className) {
+ return className.charAt(0) == ARRAY_INDICATOR;
+ }
+
+ /**
+ * Return the "element type" of the specified class.
+ * The element type is the base type held by an array type.
+ * A non-array type simply returns itself.
+ * Class#getElementType()
+ */
+ public static Class<?> elementTypeFor(Class<?> javaClass) {
+ while (javaClass.isArray()) {
+ javaClass = javaClass.getComponentType();
+ }
+ return javaClass;
+ }
+
+ /**
+ * Return the "element type" of the specified object.
+ * The element type is the base type held by an array.
+ * A non-array simply returns its class.
+ */
+ public static Class<?> elementTypeForObject(Object object) {
+ return elementTypeFor(object.getClass());
+ }
+
+ /**
+ * Return the "element type" of the specified class.
+ * The element type is the base type held by an array type.
+ * Non-array types simply return themselves.
+ * Class#getElementType()
+ */
+ public static String elementTypeNameFor(Class<?> javaClass) {
+ return elementTypeFor(javaClass).getName();
+ }
+
+ /**
+ * Return the "element type" of the specified class.
+ * The element type is the base type held by an array type.
+ * Non-array types simply return themselves.
+ * @see java.lang.Class#getName()
+ * Class#getElementType()
+ */
+ public static String elementTypeNameForClassNamed(String className) {
+ int depth = arrayDepthForClassNamed(className);
+ if (depth == 0) {
+ // the name is in the form: "java.lang.Object" or "int"
+ return className;
+ }
+ int last = className.length() - 1;
+ if (className.charAt(depth) == REFERENCE_CLASS_CODE) {
+ // the name is in the form: "[[[Ljava.lang.Object;"
+ return className.substring(depth + 1, last); // drop the trailing ';'
+ }
+ // the name is in the form: "[[[I"
+ return classNameForCode(className.charAt(last));
+ }
+
+ /**
+ * Return whether the specified class is a "reference"
+ * class (i.e. neither 'void' nor one of the primitive variable classes,
+ * ['boolean', 'int', 'float', etc.]).
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classNamedIsReference(String className) {
+ return ! classNamedIsPrimitive(className);
+ }
+
+ /**
+ * Return whether the specified class is a primitive
+ * class (i.e. 'void' or one of the primitive variable classes,
+ * ['boolean', 'int', 'float', etc.]).
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classNamedIsPrimitive(String className) {
+ if (classNamedIsArray(className) || (className.length() > maxPrimitiveClassNameLength())) {
+ return false; // performance tweak
+ }
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].javaClass.getName().equals(className)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return whether the specified class is a "variable" primitive
+ * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classNamedIsVariablePrimitive(String className) {
+ return classNamedIsPrimitive(className)
+ && ( ! className.equals(VOID_CLASS_NAME));
+ }
+
+ /**
+ * Return whether the specified class is a primitive wrapper
+ * class (i.e. 'java.lang.Void' or one of the primitive variable wrapper classes,
+ * ['java.lang.Boolean', 'java.lang.Integer', 'java.lang.Float', etc.]).
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classNamedIsPrimitiveWrapperClass(String className) {
+ if (classNamedIsArray(className) || (className.length() > maxPrimitiveWrapperClassNameLength())) {
+ return false; // performance tweak
+ }
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].wrapperClass.getName().equals(className)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return whether the specified class is a "variable" primitive
+ * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classNamedIsVariablePrimitiveWrapperClass(String className) {
+ return classNamedIsPrimitiveWrapperClass(className)
+ && ( ! className.equals(VOID_WRAPPER_CLASS_NAME));
+ }
+
+ /**
+ * Return whether the specified class is a primitive wrapper
+ * class (i.e. 'java.lang.Void' or one of the primitive variable wrapper classes,
+ * ['java.lang.Boolean', 'java.lang.Integer', 'java.lang.Float', etc.]).
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classIsPrimitiveWrapperClass(Class<?> javaClass) {
+ if (javaClass.isArray() || (javaClass.getName().length() > maxPrimitiveWrapperClassNameLength())) {
+ return false; // performance tweak
+ }
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].wrapperClass == javaClass) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return whether the specified class is a "variable" primitive
+ * class (i.e. 'boolean', 'int', 'float', etc., but not 'void').
+ * NB: void.class.isPrimitive() == true
+ */
+ public static boolean classIsVariablePrimitiveWrapperClass(Class<?> javaClass) {
+ return classIsPrimitiveWrapperClass(javaClass)
+ && (javaClass != java.lang.Void.class);
+ }
+
+ /**
+ * Return the class name for the specified class code.
+ * @see java.lang.Class#getName()
+ */
+ public static String classNameForCode(char classCode) {
+ return classForCode(classCode).getName();
+ }
+
+ /**
+ * Return the class name for the specified class code.
+ * @see java.lang.Class#getName()
+ */
+ public static String classNameForCode(int classCode) {
+ return classNameForCode((char) classCode);
+ }
+
+ /**
+ * Return the class for the specified class code.
+ * @see java.lang.Class#getName()
+ */
+ public static Class<?> classForCode(char classCode) {
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].code == classCode) {
+ return codes[i].javaClass;
+ }
+ }
+ throw new IllegalArgumentException(String.valueOf(classCode));
+ }
+
+ /**
+ * Return the class for the specified class code.
+ * @see java.lang.Class#getName()
+ */
+ public static Class<?> classForCode(int classCode) {
+ return classForCode((char) classCode);
+ }
+
+ /**
+ * Return the class code for the specified class.
+ * @see java.lang.Class#getName()
+ */
+ public static char codeForClass(Class<?> javaClass) {
+ if (( ! javaClass.isArray()) && (javaClass.getName().length() <= maxPrimitiveClassNameLength())) {
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].javaClass == javaClass) {
+ return codes[i].code;
+ }
+ }
+ }
+ throw new IllegalArgumentException(javaClass.getName());
+ }
+
+ /**
+ * Return the class code for the specified class.
+ * @see java.lang.Class#getName()
+ */
+ public static char codeForClassNamed(String className) {
+ if (( ! classNamedIsArray(className)) && (className.length() <= maxPrimitiveClassNameLength())) {
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].javaClass.getName().equals(className)) {
+ return codes[i].code;
+ }
+ }
+ }
+ throw new IllegalArgumentException(className);
+ }
+
+ /**
+ * Return the class for the specified "type declaration".
+ */
+ public static Class<?> classForTypeDeclaration(String typeDeclaration) throws ClassNotFoundException {
+ return classForTypeDeclaration(typeDeclaration, ClassTools.class.getClassLoader());
+ }
+
+ /**
+ * Return the class for the specified "type declaration",
+ * using the specified class loader.
+ */
+ public static Class<?> classForTypeDeclaration(String typeDeclaration, ClassLoader classLoader) throws ClassNotFoundException {
+ TypeDeclaration td = typeDeclaration(typeDeclaration);
+ return classForTypeDeclaration(td.elementTypeName, td.arrayDepth);
+ }
+
+ private static TypeDeclaration typeDeclaration(String typeDeclaration) {
+ typeDeclaration = StringTools.removeAllWhitespace(typeDeclaration);
+ int arrayDepth = arrayDepthForTypeDeclaration_(typeDeclaration);
+ String elementTypeName = typeDeclaration.substring(0, typeDeclaration.length() - (arrayDepth * 2));
+ return new TypeDeclaration(elementTypeName, arrayDepth);
+ }
+
+ /**
+ * Return the class for the specified "type declaration".
+ */
+ public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth) throws ClassNotFoundException {
+ return classForTypeDeclaration(elementTypeName, arrayDepth, null);
+ }
+
+ /**
+ * Return the class for the specified "type declaration",
+ * using the specified class loader.
+ */
+ // see the "Evaluation" of jdk bug 6446627 for a discussion of loading classes
+ public static Class<?> classForTypeDeclaration(String elementTypeName, int arrayDepth, ClassLoader classLoader) throws ClassNotFoundException {
+ // primitives cannot be loaded via Class#forName(),
+ // so check for a primitive class name first
+ Primitive pcc = null;
+ if (elementTypeName.length() <= maxPrimitiveClassNameLength()) { // performance tweak
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].javaClass.getName().equals(elementTypeName)) {
+ pcc = codes[i];
+ break;
+ }
+ }
+ }
+
+ // non-array
+ if (arrayDepth == 0) {
+ return (pcc == null) ? Class.forName(elementTypeName, false, classLoader) : pcc.javaClass;
+ }
+
+ // array
+ StringBuilder sb = new StringBuilder(100);
+ for (int i = arrayDepth; i-- > 0; ) {
+ sb.append(ARRAY_INDICATOR);
+ }
+ if (pcc == null) {
+ sb.append(REFERENCE_CLASS_CODE);
+ sb.append(elementTypeName);
+ sb.append(REFERENCE_CLASS_NAME_DELIMITER);
+ } else {
+ sb.append(pcc.code);
+ }
+ return Class.forName(sb.toString(), false, classLoader);
+ }
+
+ /**
+ * Return the class name for the specified "type declaration"; e.g.
+ * "int[]" -> "[I"
+ * @see java.lang.Class#getName()
+ */
+ public static String classNameForTypeDeclaration(String typeDeclaration) {
+ TypeDeclaration td = typeDeclaration(typeDeclaration);
+ return classNameForTypeDeclaration(td.elementTypeName, td.arrayDepth);
+ }
+
+ /**
+ * Return the array depth for the specified "type declaration"; e.g.
+ * "int[]" -> 1
+ */
+ public static int arrayDepthForTypeDeclaration(String typeDeclaration) {
+ return arrayDepthForTypeDeclaration_(StringTools.removeAllWhitespace(typeDeclaration));
+ }
+
+ /*
+ * Assume no whitespace in the type declaration.
+ */
+ private static int arrayDepthForTypeDeclaration_(String typeDeclaration) {
+ int last = typeDeclaration.length() - 1;
+ int depth = 0;
+ int close = last;
+ while (typeDeclaration.charAt(close) == TYPE_DECLARATION_ARRAY_CLOSE) {
+ if (typeDeclaration.charAt(close - 1) == TYPE_DECLARATION_ARRAY_OPEN) {
+ depth++;
+ } else {
+ throw new IllegalArgumentException("invalid type declaration: " + typeDeclaration);
+ }
+ close = last - (depth * 2);
+ }
+ return depth;
+ }
+
+ /**
+ * Return the class name for the specified "type declaration".
+ * @see java.lang.Class#getName()
+ */
+ public static String classNameForTypeDeclaration(String elementTypeName, int arrayDepth) {
+ // non-array
+ if (arrayDepth == 0) {
+ return elementTypeName;
+ }
+
+ if (elementTypeName.equals(VOID_CLASS_NAME)) {
+ throw new IllegalArgumentException("'" + VOID_CLASS_NAME + "' must have an array depth of zero: " + arrayDepth + '.');
+ }
+ // array
+ StringBuilder sb = new StringBuilder(100);
+ for (int i = arrayDepth; i-- > 0; ) {
+ sb.append(ARRAY_INDICATOR);
+ }
+
+ // look for a primitive first
+ Primitive pcc = null;
+ if (elementTypeName.length() <= maxPrimitiveClassNameLength()) { // performance tweak
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ if (codes[i].javaClass.getName().equals(elementTypeName)) {
+ pcc = codes[i];
+ break;
+ }
+ }
+ }
+
+ if (pcc == null) {
+ sb.append(REFERENCE_CLASS_CODE);
+ sb.append(elementTypeName);
+ sb.append(REFERENCE_CLASS_NAME_DELIMITER);
+ } else {
+ sb.append(pcc.code);
+ }
+
+ return sb.toString();
+ }
+
+ private static int maxPrimitiveClassNameLength() {
+ if (MAX_PRIMITIVE_CLASS_NAME_LENGTH == -1) {
+ MAX_PRIMITIVE_CLASS_NAME_LENGTH = calculateMaxPrimitiveClassNameLength();
+ }
+ return MAX_PRIMITIVE_CLASS_NAME_LENGTH;
+ }
+
+ private static int calculateMaxPrimitiveClassNameLength() {
+ int max = -1;
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ int len = codes[i].javaClass.getName().length();
+ if (len > max) {
+ max = len;
+ }
+ }
+ return max;
+ }
+
+ private static int maxPrimitiveWrapperClassNameLength() {
+ if (MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH == -1) {
+ MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH = calculateMaxPrimitiveWrapperClassNameLength();
+ }
+ return MAX_PRIMITIVE_WRAPPER_CLASS_NAME_LENGTH;
+ }
+
+ private static int calculateMaxPrimitiveWrapperClassNameLength() {
+ int max = -1;
+ Primitive[] codes = primitives();
+ for (int i = codes.length; i-- > 0; ) {
+ int len = codes[i].wrapperClass.getName().length();
+ if (len > max) {
+ max = len;
+ }
+ }
+ return max;
+ }
+
+ private static Primitive[] primitives() {
+ if (PRIMITIVES == null) {
+ PRIMITIVES = buildPrimitives();
+ }
+ return PRIMITIVES;
+ }
+
+ /**
+ * NB: void.class.isPrimitive() == true
+ */
+ private static Primitive[] buildPrimitives() {
+ Primitive[] result = new Primitive[9];
+ result[0] = new Primitive(BYTE_CODE, java.lang.Byte.class);
+ result[1] = new Primitive(CHAR_CODE, java.lang.Character.class);
+ result[2] = new Primitive(DOUBLE_CODE, java.lang.Double.class);
+ result[3] = new Primitive(FLOAT_CODE, java.lang.Float.class);
+ result[4] = new Primitive(INT_CODE, java.lang.Integer.class);
+ result[5] = new Primitive(LONG_CODE, java.lang.Long.class);
+ result[6] = new Primitive(SHORT_CODE, java.lang.Short.class);
+ result[7] = new Primitive(BOOLEAN_CODE, java.lang.Boolean.class);
+ result[8] = new Primitive(VOID_CODE, java.lang.Void.class);
+ return result;
+ }
+
+ /**
+ * Suppress default constructor, ensuring non-instantiability.
+ */
+ private ClassTools() {
+ super();
+ throw new UnsupportedOperationException();
+ }
+
+
+ // ********** member classes **********
+
+ private static class Primitive {
+ final char code;
+ final Class<?> javaClass;
+ final Class<?> wrapperClass;
+ private static final String WRAPPER_CLASS_TYPE_FIELD_NAME = "TYPE";
+ // e.g. java.lang.Boolean.TYPE => boolean.class
+ Primitive(char code, Class<?> wrapperClass) {
+ this.code = code;
+ this.wrapperClass = wrapperClass;
+ this.javaClass = (Class<?>) staticFieldValue(wrapperClass, WRAPPER_CLASS_TYPE_FIELD_NAME);
+ }
+ }
+
+ private static class TypeDeclaration {
+ final String elementTypeName;
+ final int arrayDepth;
+ TypeDeclaration(String elementTypeName, int arrayDepth) {
+ this.elementTypeName = elementTypeName;
+ this.arrayDepth = arrayDepth;
+ }
+ }
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
index c411aaf4f4..ae844ed0af 100644
--- a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/JptUtilityTests.java
@@ -40,6 +40,7 @@ public class JptUtilityTests {
suite.addTestSuite(IndentingPrintWriterTests.class);
suite.addTestSuite(JavaTypeTests.class);
suite.addTestSuite(JDBCTypeTests.class);
+ suite.addTestSuite(MethodSignatureTests.class);
suite.addTestSuite(NameToolsTests.class);
suite.addTestSuite(ReverseComparatorTests.class);
suite.addTestSuite(SimpleAssociationTests.class);
diff --git a/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/MethodSignatureTests.java b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/MethodSignatureTests.java
new file mode 100644
index 0000000000..b1d6f5bc1d
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.utility.tests/src/org/eclipse/jpt/utility/tests/internal/MethodSignatureTests.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 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.utility.tests.internal;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import org.eclipse.jpt.utility.JavaType;
+import org.eclipse.jpt.utility.MethodSignature;
+import org.eclipse.jpt.utility.internal.SimpleJavaType;
+import org.eclipse.jpt.utility.internal.SimpleMethodSignature;
+
+import junit.framework.TestCase;
+
+public class MethodSignatureTests extends TestCase {
+
+ public MethodSignatureTests(String name) {
+ super(name);
+ }
+
+ public void testInvalidNameNull() throws Exception {
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature((String) null);
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInvalidNameEmpty() throws Exception {
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature("");
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInvalidParameterTypesNull() throws Exception {
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature("foo", (JavaType[]) null);
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInvalidParameterTypesNullItem() throws Exception {
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature("foo", new JavaType[1]);
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInvalidParameterTypesVoidItem() throws Exception {
+ JavaType jt = new SimpleJavaType(void.class.getName());
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature("foo", new JavaType[] {jt});
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInvalidParameterTypeNamesNull() throws Exception {
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature("foo", (String[]) null);
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInvalidParameterTypeNamesNullItem() throws Exception {
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature("foo", new String[1]);
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInvalidParameterJavaClassesNull() throws Exception {
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature("foo", (Class<?>[]) null);
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testInvalidParameterJavaClassesNullItem() throws Exception {
+ boolean exCaught = false;
+ try {
+ MethodSignature methodSignature = new SimpleMethodSignature("foo", new Class[1]);
+ fail("invalid MethodSignature: " + methodSignature);
+ } catch (IllegalArgumentException ex) {
+ exCaught = true;
+ }
+ assertTrue(exCaught);
+ }
+
+ public void testGetSignature0() throws Exception {
+ MethodSignature ms = new SimpleMethodSignature(this.getMethod("method0"));
+ assertEquals("method0()", ms.getSignature());
+ }
+
+ public void testGetSignature1() throws Exception {
+ MethodSignature ms = new SimpleMethodSignature(this.getMethod("method1"));
+ assertEquals("method1(int)", ms.getSignature());
+ }
+
+ public void testGetSignature2() throws Exception {
+ MethodSignature ms = new SimpleMethodSignature(this.getMethod("method2"));
+ assertEquals("method2(int, java.lang.String)", ms.getSignature());
+ }
+
+ public void testGetSignature3() throws Exception {
+ MethodSignature ms = new SimpleMethodSignature(this.getMethod("method3"));
+ assertEquals("method3(int, java.lang.String, java.lang.Object[][])", ms.getSignature());
+ }
+
+ public void testGetName() throws Exception {
+ MethodSignature ms = new SimpleMethodSignature(this.getMethod("method2"));
+ assertEquals("method2", ms.getName());
+ }
+
+ public void testGetParameterTypes() throws Exception {
+ MethodSignature ms = new SimpleMethodSignature(this.getMethod("method3"));
+ JavaType[] expected = new JavaType[3];
+ expected[0] = new SimpleJavaType("int");
+ expected[1] = new SimpleJavaType("java.lang.String");
+ expected[2] = new SimpleJavaType("java.lang.Object", 2);
+ assertTrue(Arrays.equals(expected, ms.getParameterTypes()));
+ }
+
+ public void testEquals() throws Exception {
+ Object ms1 = new SimpleMethodSignature(this.getMethod("method3"));
+ Object ms2 = new SimpleMethodSignature(this.getMethod("method3"));
+ assertNotSame(ms1, ms2);
+ assertEquals(ms1, ms1);
+ assertEquals(ms1, ms2);
+ assertEquals(ms1.hashCode(), ms2.hashCode());
+
+ Object ms3 = new SimpleMethodSignature(this.getMethod("method2"));
+ assertNotSame(ms1, ms3);
+ assertFalse(ms1.equals(ms3));
+ }
+
+ public void testCompareTo1() throws Exception {
+ MethodSignature ms1 = new SimpleMethodSignature(this.getMethod("method3"));
+ MethodSignature ms2 = new SimpleMethodSignature(this.getMethod("method3"));
+ assertEquals(0, ms1.compareTo(ms2));
+ }
+
+ public void testCompareTo2() throws Exception {
+ MethodSignature ms1 = new SimpleMethodSignature(this.getMethod("method3"));
+ MethodSignature ms2 = new SimpleMethodSignature(this.getMethod("method2"));
+ assertTrue(ms1.compareTo(ms2) > 0);
+ }
+
+ public void testCompareTo3() throws Exception {
+ MethodSignature msA1 = new SimpleMethodSignature(this.getMethod("methodA", new Class[] {int.class, String.class}));
+ MethodSignature msA2 = new SimpleMethodSignature(this.getMethod("methodA", new Class[] {int.class, String.class, String.class}));
+ assertTrue(msA1.compareTo(msA2) < 0);
+ }
+
+ public void testCompareTo4() throws Exception {
+ MethodSignature msB1 = new SimpleMethodSignature(this.getMethod("methodB", new Class[] {int.class, Object.class}));
+ MethodSignature msB2 = new SimpleMethodSignature(this.getMethod("methodB", new Class[] {int.class, String.class}));
+ assertTrue(msB1.compareTo(msB2) < 0);
+ }
+
+ public void testClone() throws Exception {
+ SimpleMethodSignature ms1 = new SimpleMethodSignature(this.getMethod("method3"));
+ SimpleMethodSignature ms2 = (SimpleMethodSignature) ms1.clone();
+ assertNotSame(ms1, ms2);
+ assertEquals(ms1, ms2);
+ }
+
+ public void testSerialization() throws Exception {
+ SimpleMethodSignature ms1 = new SimpleMethodSignature(this.getMethod("method3"));
+ SimpleMethodSignature ms2 = TestTools.serialize(ms1);
+ assertNotSame(ms1, ms2);
+ assertEquals(ms1, ms2);
+ }
+
+ private Method getMethod(String methodName) {
+ for (Method method : this.getClass().getMethods()) {
+ if (method.getName().equals(methodName)) {
+ return method;
+ }
+ }
+ throw new IllegalArgumentException("method not found: " + methodName);
+ }
+
+ private Method getMethod(String methodName, Class<?>... parameterTypes) throws Exception {
+ return this.getClass().getMethod(methodName, parameterTypes);
+ }
+
+ public void method0() { /* used by tests */ }
+ public void method1(int foo) { /* used by tests */ }
+ public void method2(int foo, String bar) { /* used by tests */ }
+ public void method3(int foo, String bar, Object[][] baz) { /* used by tests */ }
+
+ public void methodA(int foo, String bar) { /* used by tests */ }
+ public void methodA(int foo, String bar, String baz) { /* used by tests */ }
+
+ public void methodB(int foo, Object bar) { /* used by tests */ }
+ public void methodB(int foo, String bar) { /* used by tests */ }
+
+}

Back to the top