diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary')
9 files changed, 552 insertions, 296 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAnnotation.java index e558220bcd..7d5b6bf1ec 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAnnotation.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAnnotation.java @@ -55,7 +55,7 @@ public abstract class BinaryAnnotation /** * Return the JDT annotation's member-value pair with the specified name. */ - protected IMemberValuePair getJdtMemberValuePair(String memberName) { + private IMemberValuePair getJdtMemberValuePair(String memberName) { for (IMemberValuePair pair : this.getJdtMemberValuePairs()) { if (pair.getMemberName().equals(memberName)) { return pair; @@ -64,7 +64,7 @@ public abstract class BinaryAnnotation return null; } - protected IMemberValuePair[] getJdtMemberValuePairs() { + private IMemberValuePair[] getJdtMemberValuePairs() { try { return this.jdtAnnotation.getMemberValuePairs(); } catch (JavaModelException ex) { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryNode.java index 0b3dd1f01b..2dce18dcf5 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryNode.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryNode.java @@ -13,12 +13,13 @@ import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.internal.resource.java.AbstractJavaResourceNode; import org.eclipse.jpt.core.resource.java.JavaResourceCompilationUnit; import org.eclipse.jpt.core.resource.java.JavaResourceNode; -import org.eclipse.jpt.core.resource.java.JavaResourcePackageFragmentRoot; import org.eclipse.jpt.core.utility.TextRange; /** * Binary convenience methods */ +// TODO hopefully this class can go away with some sort of refactoring of the +// source and binary hierarchies... public abstract class BinaryNode extends AbstractJavaResourceNode { @@ -32,11 +33,6 @@ public abstract class BinaryNode // ********** JavaResourceNode implementation ********** - @Override - public JavaResourcePackageFragmentRoot getRoot() { - return (JavaResourcePackageFragmentRoot) super.getRoot(); - } - public void update() { // nothing by default } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPackageFragment.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPackageFragment.java index df06ef02ca..3b60ab685e 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPackageFragment.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPackageFragment.java @@ -9,18 +9,18 @@ ******************************************************************************/ package org.eclipse.jpt.core.internal.resource.java.binary; +import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.Vector; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jpt.core.JptCorePlugin; -import org.eclipse.jpt.core.internal.utility.jdt.JPTTools; import org.eclipse.jpt.core.resource.java.JavaResourceClassFile; import org.eclipse.jpt.core.resource.java.JavaResourcePackageFragment; import org.eclipse.jpt.core.resource.java.JavaResourcePackageFragmentRoot; @@ -38,8 +38,13 @@ final class BinaryPackageFragment /** JDT package fragment */ private final IPackageFragment packageFragment; - /** class files in the package fragment */ - private final Vector<JavaResourceClassFile> classFiles; + /** + * class files in the package fragment; + * we only hold class files/types that are actually annotated; + * if the unannotated types are needed (e.g. for orm.xml or an + * inheritance tree) they can be discovered on the classpath as needed + */ + private final Vector<JavaResourceClassFile> classFiles = new Vector<JavaResourceClassFile>(); // ********** construction/initialization ********** @@ -47,42 +52,25 @@ final class BinaryPackageFragment BinaryPackageFragment(JavaResourcePackageFragmentRoot parent, IPackageFragment packageFragment) { super(parent); this.packageFragment = packageFragment; - this.classFiles = this.buildClassFiles(); + this.classFiles.addAll(this.buildClassFiles()); } - private Vector<JavaResourceClassFile> buildClassFiles() { - Vector<JavaResourceClassFile> result = new Vector<JavaResourceClassFile>(); - for (IJavaElement child : this.getJDTChildren()) { - IClassFile classFile = (IClassFile) child; - IType type = this.findType(classFile); - if (this.typeIsPersistable(type)) { // we only hold persistable types - result.add(new BinaryClassFile(this, classFile, type)); + private Collection<JavaResourceClassFile> buildClassFiles() { + IJavaElement[] children = this.getJDTChildren(); + ArrayList<JavaResourceClassFile> result = new ArrayList<JavaResourceClassFile>(children.length); + for (IJavaElement child : children) { + IClassFile jdtClassFile = (IClassFile) child; + IType jdtType = jdtClassFile.getType(); + if (BinaryPersistentType.typeIsPersistable(jdtType)) { + JavaResourceClassFile classFile = new BinaryClassFile(this, jdtClassFile, jdtType); + if (classFile.getPersistentType().isPersisted()) { // we only hold annotated types + result.add(classFile); + } } } return result; } - /** - * Return the JDT type corresponding to the specified class file - * by searching the Java project's build path; as opposed to taking - * the type directly from the class file, since another type with the - * same name *may* precede the class file on the build path. - */ - private IType findType(IClassFile classFile) { - IType type = classFile.getType(); - try { - return type.getJavaProject().findType(type.getFullyQualifiedName(), (IProgressMonitor) null); - } catch (JavaModelException ex) { - return null; // ignore exception? - } - } - - private boolean typeIsPersistable(IType type) { - return (type != null) - && type.exists() - && JPTTools.typeIsPersistable(new JPTToolsAdapter(type)); - } - // ********** JarResourceNode implementation ********** @@ -108,11 +96,11 @@ final class BinaryPackageFragment return this.classFiles.size(); } - public Iterator<JavaResourcePersistentType> persistableTypes() { + public Iterator<JavaResourcePersistentType> persistedTypes() { return new TransformationIterator<JavaResourceClassFile, JavaResourcePersistentType>(this.classFiles()) { @Override protected JavaResourcePersistentType transform(JavaResourceClassFile classFile) { - return classFile.getPersistentType(); // we only hold persistable types + return classFile.getPersistentType(); // we only hold annotated types } }; } @@ -135,95 +123,4 @@ final class BinaryPackageFragment sb.append(this.packageFragment.getElementName()); } - - // ********** JPT tools adapter ********** - - /** - * JPTTools needs an adapter so it can work with either an IType - * or an ITypeBinding etc. - */ - protected class JPTToolsAdapter implements JPTTools.TypeAdapter { - private final IType type; - - protected JPTToolsAdapter(IType type) { - super(); - if (type == null) { - throw new NullPointerException(); - } - this.type = type; - } - - public int getModifiers() { - try { - return this.type.getFlags(); - } catch (JavaModelException ex) { - JptCorePlugin.log(ex); - return 0; - } - } - - public boolean isAnnotation() { - try { - return this.type.isAnnotation(); - } catch (JavaModelException ex) { - JptCorePlugin.log(ex); - return false; - } - } - - public boolean isAnonymous() { - try { - return this.type.isAnonymous(); - } catch (JavaModelException ex) { - JptCorePlugin.log(ex); - return false; - } - } - - public boolean isArray() { - return false; // ??? - } - - public boolean isEnum() { - try { - return this.type.isEnum(); - } catch (JavaModelException ex) { - JptCorePlugin.log(ex); - return false; - } - } - - public boolean isInterface() { - try { - return this.type.isInterface(); - } catch (JavaModelException ex) { - JptCorePlugin.log(ex); - return false; - } - } - - public boolean isLocal() { - try { - return this.type.isLocal(); - } catch (JavaModelException ex) { - JptCorePlugin.log(ex); - return false; - } - } - - public boolean isMember() { - try { - return this.type.isMember(); - } catch (JavaModelException ex) { - JptCorePlugin.log(ex); - return false; - } - } - - public boolean isPrimitive() { - return false; // ??? - } - - } - } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPackageFragmentRoot.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPackageFragmentRoot.java index 20a384d486..52276c41a0 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPackageFragmentRoot.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPackageFragmentRoot.java @@ -9,8 +9,10 @@ ******************************************************************************/ package org.eclipse.jpt.core.internal.resource.java.binary; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; -import java.util.ListIterator; import java.util.Vector; import org.eclipse.core.resources.IFile; @@ -19,13 +21,11 @@ import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jpt.core.JpaAnnotationProvider; -import org.eclipse.jpt.core.JpaResourceModelListener; import org.eclipse.jpt.core.JptCorePlugin; import org.eclipse.jpt.core.resource.java.JavaResourcePackageFragment; import org.eclipse.jpt.core.resource.java.JavaResourcePackageFragmentRoot; import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType; -import org.eclipse.jpt.utility.internal.ListenerList; -import org.eclipse.jpt.utility.internal.iterators.CloneListIterator; +import org.eclipse.jpt.utility.internal.iterators.CloneIterator; import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; @@ -33,36 +33,29 @@ import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; * binary package fragment root */ public final class BinaryPackageFragmentRoot - extends BinaryNode + extends RootBinaryNode implements JavaResourcePackageFragmentRoot { /** JDT package fragment root */ private final IPackageFragmentRoot packageFragmentRoot; - /** pluggable annotation provider */ - private final JpaAnnotationProvider annotationProvider; - - /** listeners notified whenever the resource model changes */ - private final ListenerList<JpaResourceModelListener> resourceModelListenerList; - /** package fragments in the JAR */ - private final Vector<JavaResourcePackageFragment> packageFragments; + private final Vector<JavaResourcePackageFragment> packageFragments = new Vector<JavaResourcePackageFragment>(); // ********** construction/initialization ********** public BinaryPackageFragmentRoot(IPackageFragmentRoot packageFragmentRoot, JpaAnnotationProvider annotationProvider) { - super(null); // the package fragment root is the root of its sub-tree + super(null, annotationProvider); // the package fragment root is the root of its sub-tree this.packageFragmentRoot = packageFragmentRoot; - this.annotationProvider = annotationProvider; - this.resourceModelListenerList = new ListenerList<JpaResourceModelListener>(JpaResourceModelListener.class); - this.packageFragments = this.buildPackageFragments(); + this.packageFragments.addAll(this.buildPackageFragments()); } - private Vector<JavaResourcePackageFragment> buildPackageFragments() { - Vector<JavaResourcePackageFragment> result = new Vector<JavaResourcePackageFragment>(); - for (IJavaElement pf : this.getJDTChildren()) { - result.add(new BinaryPackageFragment(this, (IPackageFragment) pf)); + private Collection<JavaResourcePackageFragment> buildPackageFragments() { + IJavaElement[] jdtChildren = this.getJDTChildren(); + ArrayList<JavaResourcePackageFragment> result = new ArrayList<JavaResourcePackageFragment>(jdtChildren.length); + for (IJavaElement child : jdtChildren) { + result.add(new BinaryPackageFragment(this, (IPackageFragment) child)); } return result; } @@ -71,26 +64,11 @@ public final class BinaryPackageFragmentRoot // ********** overrides ********** @Override - protected boolean requiresParent() { - return false; - } - - @Override - public JavaResourcePackageFragmentRoot getRoot() { - return this; - } - - @Override public IFile getFile() { return (IFile) this.packageFragmentRoot.getResource(); } @Override - public JpaAnnotationProvider getAnnotationProvider() { - return this.annotationProvider; - } - - @Override public void update() { super.update(); this.updatePackageFragments(); @@ -104,41 +82,27 @@ public final class BinaryPackageFragmentRoot // ********** JavaResourceNode.Root implementation ********** - public Iterator<JavaResourcePersistentType> persistableTypes() { - return new CompositeIterator<JavaResourcePersistentType>(this.persistableTypeIterators()); + /** + * NB: we hold only annotated types + */ + public Iterator<JavaResourcePersistentType> persistentTypes() { + return new CompositeIterator<JavaResourcePersistentType>(this.persistedTypeIterators()); } - private Iterator<Iterator<JavaResourcePersistentType>> persistableTypeIterators() { + private Iterator<Iterator<JavaResourcePersistentType>> persistedTypeIterators() { return new TransformationIterator<JavaResourcePackageFragment, Iterator<JavaResourcePersistentType>>(this.packageFragments()) { @Override - protected Iterator<JavaResourcePersistentType> transform(JavaResourcePackageFragment pf) { - return pf.persistableTypes(); + protected Iterator<JavaResourcePersistentType> transform(JavaResourcePackageFragment fragment) { + return fragment.persistedTypes(); } }; } - public void resourceModelChanged() { - for (JpaResourceModelListener listener : this.resourceModelListenerList.getListeners()) { - listener.resourceModelChanged(); - } - } - - - // ********** JpaResourceModel implementation ********** - - public void addResourceModelListener(JpaResourceModelListener listener) { - this.resourceModelListenerList.add(listener); - } - - public void removeResourceModelListener(JpaResourceModelListener listener) { - this.resourceModelListenerList.remove(listener); - } - // ********** JavaResourcePackageFragmentRoot implementation ********** - public ListIterator<JavaResourcePackageFragment> packageFragments() { - return new CloneListIterator<JavaResourcePackageFragment>(this.packageFragments); + public Iterator<JavaResourcePackageFragment> packageFragments() { + return new CloneIterator<JavaResourcePackageFragment>(this.packageFragments); } public int packageFragmentsSize() { @@ -152,11 +116,14 @@ public final class BinaryPackageFragmentRoot try { return this.packageFragmentRoot.getChildren(); } catch (JavaModelException ex) { - JptCorePlugin.log(ex); + // ignore FNFE - which can happen when the workspace is out of synch with O/S file system + if ( ! (ex.getCause() instanceof FileNotFoundException)) { + JptCorePlugin.log(ex); + } return EMPTY_JAVA_ELEMENT_ARRAY; } } - protected static final IJavaElement[] EMPTY_JAVA_ELEMENT_ARRAY = new IJavaElement[0]; + private static final IJavaElement[] EMPTY_JAVA_ELEMENT_ARRAY = new IJavaElement[0]; @Override public void toString(StringBuilder sb) { diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentAttribute.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentAttribute.java index 1a0cdb8319..57856d736e 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentAttribute.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentAttribute.java @@ -72,10 +72,12 @@ final class BinaryPersistentAttribute super(parent, adapter); this.modifiers = this.buildModifiers(); this.typeName = this.buildTypeName(); - this.typeIsInterface = this.buildTypeIsInterface(); - this.typeIsEnum = this.buildTypeIsEnum(); - this.typeSuperclassNames.addAll(this.buildTypeSuperclassNames()); - this.typeInterfaceNames.addAll(this.buildTypeInterfaceNames()); + + IType type = this.getType(); // shouldn't be an array... + this.typeIsInterface = this.buildTypeIsInterface(type); + this.typeIsEnum = this.buildTypeIsEnum(type); + this.typeSuperclassNames.addAll(this.buildTypeSuperclassNames(type)); + this.typeInterfaceNames.addAll(this.buildTypeInterfaceNames(type)); this.typeTypeArgumentNames.addAll(this.buildTypeTypeArgumentNames()); } @@ -87,10 +89,12 @@ final class BinaryPersistentAttribute super.update(); this.setModifiers(this.buildModifiers()); this.setTypeName(this.buildTypeName()); - this.setTypeIsInterface(this.buildTypeIsInterface()); - this.setTypeIsEnum(this.buildTypeIsEnum()); - this.setTypeSuperclassNames(this.buildTypeSuperclassNames()); - this.setTypeInterfaceNames(this.buildTypeInterfaceNames()); + + IType type = this.getType(); // shouldn't be an array... + this.setTypeIsInterface(this.buildTypeIsInterface(type)); + this.setTypeIsEnum(this.buildTypeIsEnum(type)); + this.setTypeSuperclassNames(this.buildTypeSuperclassNames(type)); + this.setTypeInterfaceNames(this.buildTypeInterfaceNames(type)); this.setTypeTypeArgumentNames(this.buildTypeTypeArgumentNames()); } @@ -214,7 +218,7 @@ final class BinaryPersistentAttribute /** * JARs don't have array types; - * also, no generic type arguments + * also, no generic type parameters */ private String buildTypeName() { return convertTypeSignatureToTypeName(this.getTypeSignature()); @@ -231,8 +235,7 @@ final class BinaryPersistentAttribute this.firePropertyChanged(TYPE_IS_INTERFACE_PROPERTY, old, typeIsInterface); } - private boolean buildTypeIsInterface() { - IType type = this.getType(); // shouldn't be an array... + private boolean buildTypeIsInterface(IType type) { try { return (type != null) && type.isInterface(); } catch (JavaModelException ex) { @@ -252,8 +255,7 @@ final class BinaryPersistentAttribute this.firePropertyChanged(TYPE_IS_ENUM_PROPERTY, old, typeIsEnum); } - private boolean buildTypeIsEnum() { - IType type = this.getType(); // shouldn't be an array... + private boolean buildTypeIsEnum(IType type) { try { return (type != null) && type.isEnum(); } catch (JavaModelException ex) { @@ -275,8 +277,7 @@ final class BinaryPersistentAttribute this.synchronizeList(typeSuperclassNames, this.typeSuperclassNames, TYPE_SUPERCLASS_NAMES_COLLECTION); } - private List<String> buildTypeSuperclassNames() { - IType type = this.getType(); + private List<String> buildTypeSuperclassNames(IType type) { if (type == null) { return Collections.emptyList(); } @@ -284,7 +285,7 @@ final class BinaryPersistentAttribute ArrayList<String> names = new ArrayList<String>(); type = this.findSuperclass(type); while (type != null) { - names.add(type.getFullyQualifiedName()); + names.add(type.getFullyQualifiedName()); // no parameters are included here type = this.findSuperclass(type); } return names; @@ -303,8 +304,7 @@ final class BinaryPersistentAttribute this.synchronizeCollection(typeInterfaceNames, this.typeInterfaceNames, TYPE_INTERFACE_NAMES_COLLECTION); } - private Collection<String> buildTypeInterfaceNames() { - IType type = this.getType(); + private Collection<String> buildTypeInterfaceNames(IType type) { if (type == null) { return Collections.emptySet(); } @@ -403,21 +403,6 @@ final class BinaryPersistentAttribute } private static final String[] EMPTY_STRING_ARRAY = new String[0]; - /** - * Strip off the type signature's parameters if present. - * Convert to a readable string. - */ - private static String convertTypeSignatureToTypeName(String typeSignature) { - return (typeSignature == null) ? null : convertTypeSignatureToTypeName_(typeSignature); - } - - /** - * no null check - */ - private static String convertTypeSignatureToTypeName_(String typeSignature) { - return Signature.toString(Signature.getTypeErasure(typeSignature)); - } - private IType findTypeBySignature(String typeSignature) { return (typeSignature == null) ? null : this.findType(convertTypeSignatureToTypeName_(typeSignature)); } @@ -440,16 +425,39 @@ final class BinaryPersistentAttribute } + // ********** adapters ********** - interface Adapter extends BinaryPersistentMember.Adapter { + /** + * Adapt an IField or IMethod. + */ + interface Adapter + extends BinaryPersistentMember.Adapter + { + /** + * Return the field or getter method's "attribute" name + * (e.g. field "foo" -> "foo"; method "getFoo" -> "foo"). + */ String getAttributeName(); + + /** + * Return whether the attribute is a Java field (as opposed to a method). + */ boolean isField(); + + /** + * Return the attribute's type signature. + */ String getTypeSignature() throws JavaModelException; } - static class FieldAdapter implements Adapter { - private final IField field; + /** + * IField adapter + */ + static class FieldAdapter + implements Adapter + { + final IField field; FieldAdapter(IField field) { super(); @@ -461,7 +469,7 @@ final class BinaryPersistentAttribute } public boolean isPersistable() { - return this.field.exists() && JPTTools.fieldIsPersistable(new JPTToolsAdapter(this.field)); + return this.field.exists() && JPTTools.fieldIsPersistable(new JPTToolsAdapter()); } public IAnnotation[] getAnnotations() throws JavaModelException { @@ -484,20 +492,10 @@ final class BinaryPersistentAttribute * JPTTools needs an adapter so it can work with either an IField * or an IVariableBinding etc. */ - static class JPTToolsAdapter implements JPTTools.FieldAdapter { - private final IField field; - - JPTToolsAdapter(IField field) { - super(); - if (field == null) { - throw new NullPointerException(); - } - this.field = field; - } - + class JPTToolsAdapter implements JPTTools.FieldAdapter { public int getModifiers() { try { - return this.field.getFlags(); + return FieldAdapter.this.field.getFlags(); } catch (JavaModelException ex) { JptCorePlugin.log(ex); return 0; @@ -508,8 +506,14 @@ final class BinaryPersistentAttribute } - static class MethodAdapter implements Adapter { - private final IMethod method; + /** + * IMethod adapter + */ + static class MethodAdapter + implements Adapter + { + final IMethod method; + static final IMethod[] EMPTY_METHOD_ARRAY = new IMethod[0]; MethodAdapter(IMethod method) { super(); @@ -521,7 +525,7 @@ final class BinaryPersistentAttribute } public boolean isPersistable() { - return JPTTools.methodIsPersistablePropertyGetter(new JPTToolsAdapter(this.method)); + return JPTTools.methodIsPersistablePropertyGetter(new JPTToolsAdapter()); } public IAnnotation[] getAnnotations() throws JavaModelException { @@ -544,37 +548,31 @@ final class BinaryPersistentAttribute * JPTTools needs an adapter so it can work with either an IMethod * or an IMethodBinding etc. */ - static class JPTToolsAdapter implements JPTTools.MethodAdapter { - private final IMethod method; - - JPTToolsAdapter(IMethod method) { + abstract static class AbstractJPTToolsAdapter + implements JPTTools.SimpleMethodAdapter + { + AbstractJPTToolsAdapter() { super(); - if (method == null) { - throw new NullPointerException(); - } - this.method = method; } - public String getName() { - return this.method.getElementName(); - } + abstract IMethod getMethod(); public int getModifiers() { try { - return this.method.getFlags(); + return this.getMethod().getFlags(); } catch (JavaModelException ex) { JptCorePlugin.log(ex); return 0; } } - public String getReturnTypeName() { - return Signature.toString(this.getReturnTypeSignature()); + public String getReturnTypeErasureName() { + return convertTypeSignatureToTypeName(this.getReturnTypeSignature()); } private String getReturnTypeSignature() { try { - return this.method.getReturnType(); + return this.getMethod().getReturnType(); } catch (JavaModelException ex) { JptCorePlugin.log(ex); return null; @@ -583,34 +581,70 @@ final class BinaryPersistentAttribute public boolean isConstructor() { try { - return this.method.isConstructor(); + return this.getMethod().isConstructor(); } catch (JavaModelException ex) { JptCorePlugin.log(ex); return false; } } + } + + static class SimpleJPTToolsAdapter + extends AbstractJPTToolsAdapter + { + private final IMethod method; + + SimpleJPTToolsAdapter(IMethod method) { + super(); + this.method = method; + } + + @Override + IMethod getMethod() { + return this.method; + } + + } + + class JPTToolsAdapter + extends AbstractJPTToolsAdapter + implements JPTTools.MethodAdapter + { + JPTToolsAdapter() { + super(); + } + + @Override + IMethod getMethod() { + return MethodAdapter.this.method; + } + + public String getName() { + return this.getMethod().getElementName(); + } + public int getParametersLength() { - return this.method.getParameterTypes().length; + return this.getMethod().getParameterTypes().length; } - public JPTTools.MethodAdapter getSibling(String name) { + public JPTTools.SimpleMethodAdapter getSibling(String name) { for (IMethod sibling : this.getSiblings()) { if ((sibling.getParameterTypes().length == 0) && sibling.getElementName().equals(name)) { - return new JPTToolsAdapter(sibling); + return new SimpleJPTToolsAdapter(sibling); } } return null; } - public JPTTools.MethodAdapter getSibling(String name, String parameterTypeName) { + public JPTTools.SimpleMethodAdapter getSibling(String name, String parameterTypeErasureName) { for (IMethod sibling : this.getSiblings()) { String[] parmTypes = sibling.getParameterTypes(); if ((parmTypes.length == 1) - && Signature.toString(parmTypes[0]).equals(parameterTypeName) - && sibling.getElementName().equals(name)) { - return new JPTToolsAdapter(sibling); + && sibling.getElementName().equals(name) + && convertTypeSignatureToTypeName(parmTypes[0]).equals(parameterTypeErasureName)) { + return new SimpleJPTToolsAdapter(sibling); } } return null; @@ -618,13 +652,12 @@ final class BinaryPersistentAttribute private IMethod[] getSiblings() { try { - return this.method.getDeclaringType().getMethods(); + return this.getMethod().getDeclaringType().getMethods(); } catch (JavaModelException ex) { JptCorePlugin.log(ex); return EMPTY_METHOD_ARRAY; } } - private static final IMethod[] EMPTY_METHOD_ARRAY = new IMethod[0]; } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentMember.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentMember.java index 92e2c59406..00302570b9 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentMember.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentMember.java @@ -16,6 +16,7 @@ import java.util.Vector; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jpt.core.JptCorePlugin; import org.eclipse.jpt.core.resource.java.Annotation; @@ -107,7 +108,7 @@ abstract class BinaryPersistentMember public Annotation getMappingAnnotation() { Iterable<Annotation> annotations = new FixedCloneIterable<Annotation>(this.mappingAnnotations); for (ListIterator<String> stream = this.validMappingAnnotationNames(); stream.hasNext();) { - Annotation annotation = this.getAnnotation(annotations, stream.next()); + Annotation annotation = this.selectAnnotationNamed(annotations, stream.next()); if (annotation != null) { return annotation; } @@ -116,7 +117,7 @@ abstract class BinaryPersistentMember } public Annotation getMappingAnnotation(String annotationName) { - return this.getAnnotation(this.getMappingAnnotations(), annotationName); + return this.selectAnnotationNamed(this.getMappingAnnotations(), annotationName); } private boolean annotationIsValidMappingAnnotation(IAnnotation jdtAnnotation) { @@ -148,7 +149,9 @@ abstract class BinaryPersistentMember return containerAnnotation.nestedAnnotations(); } NestableAnnotation nestableAnnotation = this.getSupportingNestableAnnotation(nestableAnnotationName); - return (nestableAnnotation == null) ? EmptyListIterator.<NestableAnnotation>instance() : new SingleElementListIterator<NestableAnnotation>(nestableAnnotation); + return (nestableAnnotation == null) ? + EmptyListIterator.<NestableAnnotation>instance() : + new SingleElementListIterator<NestableAnnotation>(nestableAnnotation); } private NestableAnnotation getSupportingNestableAnnotation(String annotationName) { @@ -156,7 +159,7 @@ abstract class BinaryPersistentMember } public Annotation getSupportingAnnotation(String annotationName) { - return this.getAnnotation(this.getSupportingAnnotations(), annotationName); + return this.selectAnnotationNamed(this.getSupportingAnnotations(), annotationName); } public Annotation getNonNullSupportingAnnotation(String annotationName) { @@ -203,11 +206,11 @@ abstract class BinaryPersistentMember // ********** miscellaneous ********** - public IMember getMember() { + IMember getMember() { return this.adapter.getMember(); } - private Annotation getAnnotation(Iterable<Annotation> annotations, String annotationName) { + private Annotation selectAnnotationNamed(Iterable<Annotation> annotations, String annotationName) { for (Annotation annotation : annotations) { if (annotation.getAnnotationName().equals(annotationName)) { return annotation; @@ -228,6 +231,21 @@ abstract class BinaryPersistentMember }; } + /** + * Strip off the type signature's parameters if present. + * Convert to a readable string. + */ + static String convertTypeSignatureToTypeName(String typeSignature) { + return (typeSignature == null) ? null : convertTypeSignatureToTypeName_(typeSignature); + } + + /** + * no null check + */ + static String convertTypeSignatureToTypeName_(String typeSignature) { + return Signature.toString(Signature.getTypeErasure(typeSignature)); + } + private IAnnotation[] getJdtAnnotations() { try { return this.adapter.getAnnotations(); @@ -242,8 +260,20 @@ abstract class BinaryPersistentMember // ********** IMember adapter ********** interface Adapter { + /** + * Return the adapter's JDT member (IType, IField, IMethod). + */ IMember getMember(); + + /** + * Return whether the adapter's member is "persistable" + * (i.e. according to the JPA spec the member can be mapped) + */ boolean isPersistable(); + + /** + * Return the adapter's member's JDT annotations. + */ IAnnotation[] getAnnotations() throws JavaModelException; } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentType.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentType.java index 4df1330f3a..b652e88abe 100644 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentType.java +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentType.java @@ -24,7 +24,7 @@ import org.eclipse.jpt.core.JptCorePlugin; 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.JavaResourceClassFile; +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.utility.MethodSignature; @@ -44,7 +44,7 @@ final class BinaryPersistentType private String qualifiedName; - private String superClassQualifiedName; + private String superclassQualifiedName; private boolean abstract_; // 'abstract' is a reserved word @@ -57,11 +57,11 @@ final class BinaryPersistentType // ********** construction/initialization ********** - BinaryPersistentType(JavaResourceClassFile parent, IType type) { + BinaryPersistentType(JavaResourceNode parent, IType type) { super(parent, new TypeAdapter(type)); this.name = this.buildName(); this.qualifiedName = this.buildQualifiedName(); - this.superClassQualifiedName = this.buildSuperClassQualifiedName(); + this.superclassQualifiedName = this.buildSuperclassQualifiedName(); this.abstract_ = this.buildAbstract(); this.fields = this.buildFields(); this.methods = this.buildMethods(); @@ -77,10 +77,11 @@ final class BinaryPersistentType super.update(); this.setName(this.buildName()); this.setQualifiedName(this.buildQualifiedName()); - this.setSuperClassQualifiedName(this.buildSuperClassQualifiedName()); + this.setSuperclassQualifiedName(this.buildSuperclassQualifiedName()); this.setAbstract(this.buildAbstract()); this.updateFields(); this.updateMethods(); + // need to wait until everything is updated to calculate 'access' this.setAccess(this.buildAccess()); } @@ -157,23 +158,27 @@ final class BinaryPersistentType } private String buildQualifiedName() { - return this.getMember().getFullyQualifiedName(); + return this.getMember().getFullyQualifiedName(); // no parameters are included here } // ***** superclass qualified name - public String getSuperClassQualifiedName() { - return this.superClassQualifiedName; + public String getSuperclassQualifiedName() { + return this.superclassQualifiedName; } - private void setSuperClassQualifiedName(String superClassQualifiedName) { - String old = this.superClassQualifiedName; - this.superClassQualifiedName = superClassQualifiedName; - this.firePropertyChanged(SUPER_CLASS_QUALIFIED_NAME_PROPERTY, old, superClassQualifiedName); + private void setSuperclassQualifiedName(String superclassQualifiedName) { + String old = this.superclassQualifiedName; + this.superclassQualifiedName = superclassQualifiedName; + this.firePropertyChanged(SUPERCLASS_QUALIFIED_NAME_PROPERTY, old, superclassQualifiedName); } - private String buildSuperClassQualifiedName() { + private String buildSuperclassQualifiedName() { + return convertTypeSignatureToTypeName(this.getSuperclassTypeSignature()); + } + + private String getSuperclassTypeSignature() { try { - return this.getMember().getSuperclassName(); + return this.getMember().getSuperclassTypeSignature(); } catch (JavaModelException ex) { JptCorePlugin.log(ex); return null; @@ -397,6 +402,8 @@ final class BinaryPersistentType } + // ********** IType adapter ********** + static class TypeAdapter implements Adapter { private final IType type; @@ -420,6 +427,106 @@ final class BinaryPersistentType } + // ********** "persistable" check ********** + + static boolean typeIsPersistable(IType type) { + return (type != null) + && type.exists() + && JPTTools.typeIsPersistable(new JPTToolsAdapter(type)); + } + + + // ********** JPT tools adapter ********** + + /** + * JPTTools needs an adapter so it can work with either an IType + * or an ITypeBinding etc. + */ + static class JPTToolsAdapter implements JPTTools.TypeAdapter { + private final IType type; + + protected JPTToolsAdapter(IType type) { + super(); + if (type == null) { + throw new NullPointerException(); + } + this.type = type; + } + + public int getModifiers() { + try { + return this.type.getFlags(); + } catch (JavaModelException ex) { + JptCorePlugin.log(ex); + return 0; + } + } + + public boolean isAnnotation() { + try { + return this.type.isAnnotation(); + } catch (JavaModelException ex) { + JptCorePlugin.log(ex); + return false; + } + } + + public boolean isAnonymous() { + try { + return this.type.isAnonymous(); + } catch (JavaModelException ex) { + JptCorePlugin.log(ex); + return false; + } + } + + public boolean isArray() { + return false; // ??? + } + + public boolean isEnum() { + try { + return this.type.isEnum(); + } catch (JavaModelException ex) { + JptCorePlugin.log(ex); + return false; + } + } + + public boolean isInterface() { + try { + return this.type.isInterface(); + } catch (JavaModelException ex) { + JptCorePlugin.log(ex); + return false; + } + } + + public boolean isLocal() { + try { + return this.type.isLocal(); + } catch (JavaModelException ex) { + JptCorePlugin.log(ex); + return false; + } + } + + public boolean isMember() { + try { + return this.type.isMember(); + } catch (JavaModelException ex) { + JptCorePlugin.log(ex); + return false; + } + } + + public boolean isPrimitive() { + return false; // ??? + } + + } + + // ********** unsupported JavaResourcePersistentType implementation ********** public Iterator<JavaResourcePersistentType> types() { @@ -434,8 +541,4 @@ final class BinaryPersistentType throw new UnsupportedOperationException(); } - public Iterator<JavaResourcePersistentType> allPersistableTypes() { - throw new UnsupportedOperationException(); - } - } diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentTypeCache.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentTypeCache.java new file mode 100644 index 0000000000..70dbb73433 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryPersistentTypeCache.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2009 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.core.internal.resource.java.binary; + +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.jdt.core.IType; +import org.eclipse.jpt.core.JpaAnnotationProvider; +import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType; +import org.eclipse.jpt.core.resource.java.JavaResourcePersistentTypeCache; +import org.eclipse.jpt.utility.internal.iterables.CloneIterable; +import org.eclipse.jpt.utility.internal.iterables.TransformationIterable; +import org.eclipse.jpt.utility.internal.StringTools; + +/** + * cache used to hold binary "external" Java resource persistent types + * (typically derived from JARs on the project's build path) + */ +public final class BinaryPersistentTypeCache + extends RootBinaryNode + implements JavaResourcePersistentTypeCache +{ + /** populated on-demand */ + private final Vector<Entry> entries = new Vector<Entry>(); + + + // ********** construction ********** + + public BinaryPersistentTypeCache(JpaAnnotationProvider annotationProvider) { + super(null, annotationProvider); + } + + + // ********** JavaResourceNode.Root implementation ********** + + public Iterator<JavaResourcePersistentType> persistentTypes() { + return this.getPersistentTypes().iterator(); + } + + private Iterable<JavaResourcePersistentType> getPersistentTypes() { + return new TransformationIterable<Entry, JavaResourcePersistentType>(this.getEntries()) { + @Override + protected JavaResourcePersistentType transform(Entry entry) { + return entry.persistentType; + } + }; + } + + private Iterable<Entry> getEntries() { + return new CloneIterable<Entry>(this.entries); + } + + + // ********** JavaResourcePersistentTypeCache implementation ********** + + public int persistentTypesSize() { + return this.entries.size(); + } + + public JavaResourcePersistentType addPersistentType(IType jdtType) { + Entry entry = this.buildEntry(jdtType); + this.entries.add(entry); + this.fireItemAdded(PERSISTENT_TYPES_COLLECTION, entry.persistentType); + return entry.persistentType; + } + + private Entry buildEntry(IType jdtType) { + return new Entry(this.buildPersistentType(jdtType), jdtType.getResource()); + } + + private JavaResourcePersistentType buildPersistentType(IType jdtType) { + return new BinaryPersistentType(this, jdtType); + } + + public boolean removePersistentTypes(IFile jarFile) { + boolean modified = false; + for (Entry entry : this.getEntries()) { + IResource resource = entry.resource; + if ((resource != null) && resource.equals(jarFile)) { + this.removeEntry(entry); + modified = true; + } + } + return modified; + } + + private void removeEntry(Entry entry) { + this.entries.remove(entry); + this.fireItemRemoved(PERSISTENT_TYPES_COLLECTION, entry.persistentType); + } + + + // ********** overrides ********** + + @Override + public IFile getFile() { + return null; // ??? + } + + /** + * Ignore changes to this collection. Adds can be ignored since they are triggered + * by requests that will, themselves, trigger updates (typically during the + * update of an object that calls a setter with the newly-created resource + * type). Deletes will be accompanied by manual updates. + */ + @Override + protected void aspectChanged(String aspectName) { + if ((aspectName != null) && ! aspectName.equals(PERSISTENT_TYPES_COLLECTION)) { + super.aspectChanged(aspectName); + } + } + + @Override + public void toString(StringBuilder sb) { + sb.append(this.entries); + } + + + // ********** cache entry ********** + + /** + * Associate a persistent type with its resource. + * This will be a JAR in the case of a type loaded from a JAR that is in + * the Eclipse workspace. The resource will be null for a type loaded + * from a JAR or class directory outside of the workspace. + */ + static class Entry { + final JavaResourcePersistentType persistentType; + final IResource resource; + + Entry(JavaResourcePersistentType persistentType, IResource resource) { + super(); + this.persistentType = persistentType; + this.resource = resource; + } + + @Override + public String toString() { + return StringTools.buildToStringFor(this, this.persistentType); + } + + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/RootBinaryNode.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/RootBinaryNode.java new file mode 100644 index 0000000000..be9981c144 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/RootBinaryNode.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2009 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.core.internal.resource.java.binary; + +import org.eclipse.jpt.core.JpaAnnotationProvider; +import org.eclipse.jpt.core.JpaResourceModelListener; +import org.eclipse.jpt.core.resource.java.JavaResourceNode; +import org.eclipse.jpt.utility.internal.ListenerList; + +/** + * JAR and external types + */ +abstract class RootBinaryNode + extends BinaryNode + implements JavaResourceNode.Root +{ + /** pluggable annotation provider */ + private final JpaAnnotationProvider annotationProvider; + + /** listeners notified whenever the resource model changes */ + private final ListenerList<JpaResourceModelListener> resourceModelListenerList = new ListenerList<JpaResourceModelListener>(JpaResourceModelListener.class); + + + // ********** construction ********** + + RootBinaryNode(JavaResourceNode parent, JpaAnnotationProvider annotationProvider) { + super(parent); + this.annotationProvider = annotationProvider; + } + + + // ********** overrides ********** + + @Override + protected boolean requiresParent() { + return false; + } + + @Override + public Root getRoot() { + return this; + } + + @Override + public JpaAnnotationProvider getAnnotationProvider() { + return this.annotationProvider; + } + + + // ********** JavaResourceNode.Root implementation ********** + + public void resourceModelChanged() { + for (JpaResourceModelListener listener : this.resourceModelListenerList.getListeners()) { + listener.resourceModelChanged(); + } + } + + + // ********** JpaResourceModel implementation ********** + + public void addResourceModelListener(JpaResourceModelListener listener) { + this.resourceModelListenerList.add(listener); + } + + public void removeResourceModelListener(JpaResourceModelListener listener) { + this.resourceModelListenerList.remove(listener); + } + +} |