Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 331480 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jpt/common/core/internal/utility/JDTTools.java (+81 lines)
Lines 11-27 Link Here
11
11
12
import java.io.FileNotFoundException;
12
import java.io.FileNotFoundException;
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
15
import org.eclipse.jdt.core.Flags;
14
import org.eclipse.jdt.core.IJavaElement;
16
import org.eclipse.jdt.core.IJavaElement;
15
import org.eclipse.jdt.core.IJavaProject;
17
import org.eclipse.jdt.core.IJavaProject;
18
import org.eclipse.jdt.core.IMethod;
16
import org.eclipse.jdt.core.IPackageFragmentRoot;
19
import org.eclipse.jdt.core.IPackageFragmentRoot;
17
import org.eclipse.jdt.core.IParent;
20
import org.eclipse.jdt.core.IParent;
18
import org.eclipse.jdt.core.IType;
21
import org.eclipse.jdt.core.IType;
19
import org.eclipse.jdt.core.JavaModelException;
22
import org.eclipse.jdt.core.JavaModelException;
23
import org.eclipse.jdt.core.Signature;
20
import org.eclipse.jpt.common.core.JptCommonCorePlugin;
24
import org.eclipse.jpt.common.core.JptCommonCorePlugin;
21
import org.eclipse.jpt.common.utility.Filter;
25
import org.eclipse.jpt.common.utility.Filter;
22
import org.eclipse.jpt.common.utility.internal.ArrayTools;
26
import org.eclipse.jpt.common.utility.internal.ArrayTools;
23
import org.eclipse.jpt.common.utility.internal.ClassName;
27
import org.eclipse.jpt.common.utility.internal.ClassName;
24
import org.eclipse.jpt.common.utility.internal.ReflectionTools;
28
import org.eclipse.jpt.common.utility.internal.ReflectionTools;
29
import org.eclipse.jpt.common.utility.internal.StringTools;
25
import org.eclipse.jpt.common.utility.internal.iterables.ArrayIterable;
30
import org.eclipse.jpt.common.utility.internal.iterables.ArrayIterable;
26
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
31
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
27
import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
32
import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
Lines 105-110 Link Here
105
	}
110
	}
106
111
107
	/**
112
	/**
113
	 * Return true if the given type named contains a method name as given with the given paramter types
114
	 */
115
	public static boolean typeNamedImplementsMethod(IJavaProject javaProject, String typeName, String methodName, String[] parameterTypeNames) {
116
		try {
117
			return typeImplementsMethod(javaProject, javaProject.findType(typeName), methodName, parameterTypeNames);
118
		} catch (JavaModelException ex) {
119
			JptCommonCorePlugin.log(ex);
120
			return false;
121
		}
122
	}
123
	
124
	private static boolean typeImplementsMethod(IJavaProject javaProject, IType type, String methodName, String[] parameterTypeNames) {
125
		if ((type == null) || methodName == null) {
126
			return false;
127
		}
128
				
129
		try {
130
			IMethod[] methods = type.getMethods();
131
			for (IMethod method : methods) {
132
				if (StringTools.stringsAreEqual(method.getElementName(), methodName)) {
133
					if (parameterTypeNames.length == 0 && method.getNumberOfParameters() == 0) {
134
						return true;
135
					} else if (parameterTypeNames.length == method.getNumberOfParameters()) {
136
						int index = 0;
137
						String[] parameters = method.getParameterTypes();
138
						String resolvedParameterTypeName = parameters[0];
139
						if (!type.isResolved()) {
140
							resolvedParameterTypeName = resolveType(type, Signature.getSignatureSimpleName(parameters[index]));
141
						}
142
						for (String parameterTypeName : parameterTypeNames) {
143
							if (!StringTools.stringsAreEqual(resolvedParameterTypeName, parameterTypeName)) {
144
								return false;
145
							}
146
							index++;
147
						}
148
						return true;
149
					}
150
				}
151
			}
152
		} catch (JavaModelException ex) {
153
			JptCommonCorePlugin.log(ex);
154
			return false;			
155
		}
156
		return false;
157
	}
158
	
159
	/**
108
	 * Return the names of the specified type's super interfaces.
160
	 * Return the names of the specified type's super interfaces.
109
	 * This is necessary because, for whatever reason, {@link IType#getSuperInterfaceNames()}
161
	 * This is necessary because, for whatever reason, {@link IType#getSuperInterfaceNames()}
110
	 * returns unqualified names when the type is from Java source.
162
	 * returns unqualified names when the type is from Java source.
Lines 273-276 Link Here
273
		java.sql.Time.class.getName(),
325
		java.sql.Time.class.getName(),
274
		java.sql.Timestamp.class.getName(),
326
		java.sql.Timestamp.class.getName(),
275
	};
327
	};
328
	
329
	public static boolean classIsPublic(IJavaProject javaProject, String className) {
330
		if (className != null) {
331
			IType embeddableType = JDTTools.findType(javaProject, className);
332
			try {
333
				return Flags.isPublic(embeddableType.getFlags());
334
			} catch (JavaModelException ex) {
335
				JptCommonCorePlugin.log(ex);
336
			}
337
		}
338
		return false;
339
	}
340
	
341
	public static boolean classHasPublicZeroArgConstructor(IJavaProject javaProject, String className) {
342
		if (javaProject != null && className != null) {
343
			IType type = findType(javaProject, className);
344
			try {
345
				for (IMethod method : type.getMethods()) {
346
					if ((method.isConstructor()) && (method.getNumberOfParameters() == 0)
347
							&& (method.getFlags() == 1)) {
348
						return true;
349
					}
350
				}
351
			} catch (JavaModelException ex) {
352
				JptCommonCorePlugin.log(ex);
353
			}
354
		}
355
		return false;
356
	}
276
}
357
}
(-)property_files/jpa_validation.properties (+5 lines)
Lines 50-55 Link Here
50
TYPE_MAPPING_ID_CLASS_REQUIRED=This class has a composite primary key.  It must use an ID class.
50
TYPE_MAPPING_ID_CLASS_REQUIRED=This class has a composite primary key.  It must use an ID class.
51
TYPE_MAPPING_ID_CLASS_AND_EMBEDDED_ID_BOTH_USED=This class must use either an ID class or an embedded ID to specify its composite primary key, not both.
51
TYPE_MAPPING_ID_CLASS_AND_EMBEDDED_ID_BOTH_USED=This class must use either an ID class or an embedded ID to specify its composite primary key, not both.
52
TYPE_MAPPING_MULTIPLE_EMBEDDED_ID=This class uses multiple embedded ID mappings.  Only one is allowed.
52
TYPE_MAPPING_MULTIPLE_EMBEDDED_ID=This class uses multiple embedded ID mappings.  Only one is allowed.
53
TYPE_MAPPING_ID_AND_EMBEDDED_ID_BOTH_USED=This class must use either an ID or and embedded ID to specify its primary key, not both.
53
TYPE_MAPPING_ID_CLASS_WITH_MAPS_ID=The relationship ''{0}'' maps an ID, which is not allowed in conjunction with an ID class.
54
TYPE_MAPPING_ID_CLASS_WITH_MAPS_ID=The relationship ''{0}'' maps an ID, which is not allowed in conjunction with an ID class.
54
TYPE_MAPPING_MAPS_ID_ATTRIBUTE_TYPE_DOES_NOT_AGREE=The type of the ID mapped by the relationship ''{0}'' does not agree with the primary key class of the target entity.
55
TYPE_MAPPING_MAPS_ID_ATTRIBUTE_TYPE_DOES_NOT_AGREE=The type of the ID mapped by the relationship ''{0}'' does not agree with the primary key class of the target entity.
55
TYPE_MAPPING_ID_CLASS_ATTRIBUTE_NO_MATCH=There is no primary key attribute to match the ID class attribute {0}
56
TYPE_MAPPING_ID_CLASS_ATTRIBUTE_NO_MATCH=There is no primary key attribute to match the ID class attribute {0}
Lines 88-93 Link Here
88
ID_MAPPING_UNRESOLVED_GENERATOR_NAME=Unresolved generator name \"{0}\"
89
ID_MAPPING_UNRESOLVED_GENERATOR_NAME=Unresolved generator name \"{0}\"
89
ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_COLUMN_SPECIFIED=In {0}, a column is specified, but it is mapped by a relationship. IDs that are mapped by a relationship should not specify a column.
90
ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_COLUMN_SPECIFIED=In {0}, a column is specified, but it is mapped by a relationship. IDs that are mapped by a relationship should not specify a column.
90
EMBEDDED_ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_ATTRIBUTE_OVERRIDES_SPECIFIED=Embedded IDs that are mapped by a relationship should not specify any attribute overrides.
91
EMBEDDED_ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_ATTRIBUTE_OVERRIDES_SPECIFIED=Embedded IDs that are mapped by a relationship should not specify any attribute overrides.
92
EMBEDDED_ID_CLASS_SHOULD_IMPLMENT_EQUALS_HASHCODE=Embedded id class should include method definitions for equals() and hashcode().
93
EMBEDDED_ID_CLASS_SHOULD_BE_PUBLIC_AND_INCLUDE_ZERO_ARG_CONSTRUCTOR=Embedded id class should be public, and include a zero argument constructor.
94
EMBEDDED_ID_CLASS_SHOULD_IMPLEMENT_SERIALIZABLE=Embedded id class should implement Serializable.
95
EMBEDDED_ID_CLASS_SHOULD_NOT_CONTAIN_RELATIONSHIP_MAPPINGS=Embedded id class should not contain relationship mappings.
91
ATTRIBUTE_OVERRIDE_MAPPED_BY_RELATIONSHIP_AND_SPECIFIED=Attributes (or subattributes of an attribute) that are mapped by a relationship should not be overridden.
96
ATTRIBUTE_OVERRIDE_MAPPED_BY_RELATIONSHIP_AND_SPECIFIED=Attributes (or subattributes of an attribute) that are mapped by a relationship should not be overridden.
92
TABLE_UNRESOLVED_CATALOG=Catalog \"{0}\" cannot be resolved for table \"{1}\"
97
TABLE_UNRESOLVED_CATALOG=Catalog \"{0}\" cannot be resolved for table \"{1}\"
93
TABLE_UNRESOLVED_SCHEMA=Schema \"{0}\" cannot be resolved for table \"{1}\"
98
TABLE_UNRESOLVED_SCHEMA=Schema \"{0}\" cannot be resolved for table \"{1}\"
(-)src/org/eclipse/jpt/jpa/core/internal/jpa1/context/AbstractEntityPrimaryKeyValidator.java (+2 lines)
Lines 73-78 Link Here
73
		validateOneOfIdClassOrEmbeddedIdIsUsed(messages, reporter);
73
		validateOneOfIdClassOrEmbeddedIdIsUsed(messages, reporter);
74
		// ... and only one embedded id
74
		// ... and only one embedded id
75
		validateOneEmbeddedId(messages, reporter);
75
		validateOneEmbeddedId(messages, reporter);
76
		// ... and not both id and embedded id
77
		validateOneOfEmbeddedOrIdIsUsed(messages, reporter);
76
		
78
		
77
		validateMapsIdMappings(messages, reporter);
79
		validateMapsIdMappings(messages, reporter);
78
		
80
		
(-)src/org/eclipse/jpt/jpa/core/internal/jpa1/context/AbstractMappedSuperclassPrimaryKeyValidator.java (+2 lines)
Lines 44-49 Link Here
44
		validateOneOfIdClassOrEmbeddedIdIsUsed(messages, reporter);
44
		validateOneOfIdClassOrEmbeddedIdIsUsed(messages, reporter);
45
		// ... and only one embedded id
45
		// ... and only one embedded id
46
		validateOneEmbeddedId(messages, reporter);
46
		validateOneEmbeddedId(messages, reporter);
47
		// ... and not both id and embedded id
48
		validateOneOfEmbeddedOrIdIsUsed(messages, reporter);
47
		
49
		
48
		if (specifiesIdClass()) {
50
		if (specifiesIdClass()) {
49
			validateIdClass(idClassReference().getIdClass(), messages, reporter);
51
			validateIdClass(idClassReference().getIdClass(), messages, reporter);
(-)src/org/eclipse/jpt/jpa/core/internal/jpa1/context/AbstractPrimaryKeyValidator.java (+22 lines)
Lines 13-18 Link Here
13
import java.util.Collection;
13
import java.util.Collection;
14
import java.util.Iterator;
14
import java.util.Iterator;
15
import java.util.List;
15
import java.util.List;
16
16
import org.eclipse.jpt.common.utility.internal.ClassName;
17
import org.eclipse.jpt.common.utility.internal.ClassName;
17
import org.eclipse.jpt.common.utility.internal.CollectionTools;
18
import org.eclipse.jpt.common.utility.internal.CollectionTools;
18
import org.eclipse.jpt.common.utility.internal.HashBag;
19
import org.eclipse.jpt.common.utility.internal.HashBag;
Lines 119-124 Link Here
119
		}
120
		}
120
	}
121
	}
121
	
122
	
123
	//only embedded or id, both may not be used
124
	protected void validateOneOfEmbeddedOrIdIsUsed(List<IMessage> messages, IReporter reporter) {
125
		if (definesEmbeddedIdMapping(typeMapping) && definesIdMapping(typeMapping)) {
126
			messages.add(
127
					DefaultJpaValidationMessages.buildMessage(
128
						IMessage.HIGH_SEVERITY,
129
						JpaValidationMessages.TYPE_MAPPING_ID_AND_EMBEDDED_ID_BOTH_USED,
130
						EMPTY_STRING_ARRAY,
131
						typeMapping(),
132
						textRangeResolver().getTypeMappingTextRange()));
133
		}
134
	}
135
	
122
	// only one embedded id may be used
136
	// only one embedded id may be used
123
	protected void validateOneEmbeddedId(List<IMessage> messages, IReporter reporter) {
137
	protected void validateOneEmbeddedId(List<IMessage> messages, IReporter reporter) {
124
		if (CollectionTools.size(getEmbeddedIdMappings(typeMapping())) > 1) {
138
		if (CollectionTools.size(getEmbeddedIdMappings(typeMapping())) > 1) {
Lines 462-467 Link Here
462
		return ! CollectionTools.isEmpty(getEmbeddedIdMappings(typeMapping));
476
		return ! CollectionTools.isEmpty(getEmbeddedIdMappings(typeMapping));
463
	}
477
	}
464
	
478
	
479
	/**
480
	 * Return whether an id is defined for this class, whether that be locally
481
	 * or on an ancestor
482
	 */
483
	protected boolean definesIdMapping(TypeMapping typeMapping) {
484
		return ! CollectionTools.isEmpty(getIdMappings(typeMapping));
485
	}
486
	
465
	protected EmbeddedIdMapping getEmbeddedIdMapping(TypeMapping typeMapping) {
487
	protected EmbeddedIdMapping getEmbeddedIdMapping(TypeMapping typeMapping) {
466
		Iterable<EmbeddedIdMapping> embeddedIdMappings = getEmbeddedIdMappings(typeMapping);
488
		Iterable<EmbeddedIdMapping> embeddedIdMappings = getEmbeddedIdMappings(typeMapping);
467
		if (CollectionTools.size(embeddedIdMappings) == 1) {
489
		if (CollectionTools.size(embeddedIdMappings) == 1) {
(-)src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddedIdMapping.java (-2 / +89 lines)
Lines 9-18 Link Here
9
 ******************************************************************************/
9
 ******************************************************************************/
10
package org.eclipse.jpt.jpa.core.internal.jpa1.context.java;
10
package org.eclipse.jpt.jpa.core.internal.jpa1.context.java;
11
11
12
import java.io.Serializable;
12
import java.util.Iterator;
13
import java.util.Iterator;
13
import java.util.List;
14
import java.util.List;
14
import java.util.Set;
15
import java.util.Set;
16
17
import org.eclipse.jdt.core.IJavaProject;
15
import org.eclipse.jdt.core.dom.CompilationUnit;
18
import org.eclipse.jdt.core.dom.CompilationUnit;
19
import org.eclipse.jpt.common.core.internal.utility.JDTTools;
16
import org.eclipse.jpt.common.utility.internal.CollectionTools;
20
import org.eclipse.jpt.common.utility.internal.CollectionTools;
17
import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator;
21
import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator;
18
import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator;
22
import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator;
Lines 109-115 Link Here
109
	@Override
113
	@Override
110
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
114
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
111
		super.validate(messages, reporter, astRoot);
115
		super.validate(messages, reporter, astRoot);
112
116
		validateMappedByRelationshipAndAttributeOverridesSpecified(messages, reporter, astRoot);
117
		validateTargeEmbeddableImplementsEqualsAndHashcode(messages, reporter, astRoot);
118
		validateTargetEmbeddableIsPublicWithZeroArgConstructor(messages, reporter, astRoot);
119
		validateTargetEmbeddableImplementsSerializable(messages, reporter, astRoot);
120
		validateNoRelationshipMappingsOnTargetEmbeddable(messages, reporter, astRoot);
121
	}
122
	
123
	protected void validateNoRelationshipMappingsOnTargetEmbeddable(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
124
		if (this.getTargetEmbeddable() != null) {
125
			TypeMapping targetEmbeddableTypeMapping = this.getTargetEmbeddable().getPersistentType().getMapping();
126
			if (targetEmbeddableTypeMapping.getAllAttributeMappings(MappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY).iterator().hasNext()
127
					|| targetEmbeddableTypeMapping.getAllAttributeMappings(MappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY).iterator().hasNext()
128
					|| targetEmbeddableTypeMapping.getAllAttributeMappings(MappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY).iterator().hasNext()
129
					|| targetEmbeddableTypeMapping.getAllAttributeMappings(MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY).iterator().hasNext()) {
130
				messages.add(
131
					DefaultJpaValidationMessages.buildMessage(
132
						IMessage.HIGH_SEVERITY,
133
						JpaValidationMessages.EMBEDDED_ID_CLASS_SHOULD_NOT_CONTAIN_RELATIONSHIP_MAPPINGS,
134
						EMPTY_STRING_ARRAY,
135
						this,
136
						this.getValidationTextRange(astRoot)
137
					)
138
				);				
139
			}
140
		}
141
	}
142
	
143
	protected void validateTargetEmbeddableImplementsSerializable(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
144
		if (this.getTargetEmbeddable() != null) {
145
			String targetEmbeddableClassName = this.getTargetEmbeddable().getPersistentType().getName();
146
			IJavaProject javaProject = getJpaProject().getJavaProject();
147
			if (!JDTTools.typeNamedImplementsInterfaceNamed(javaProject, targetEmbeddableClassName, Serializable.class.getName())) {
148
				messages.add(
149
					DefaultJpaValidationMessages.buildMessage(
150
						IMessage.HIGH_SEVERITY,
151
						JpaValidationMessages.EMBEDDED_ID_CLASS_SHOULD_IMPLEMENT_SERIALIZABLE,
152
						EMPTY_STRING_ARRAY,
153
						this,
154
						this.getValidationTextRange(astRoot)
155
					)
156
				);
157
			}
158
		}
159
	}
160
	
161
	protected void validateTargetEmbeddableIsPublicWithZeroArgConstructor(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
162
		if (this.getTargetEmbeddable() != null) {
163
			String targetEmbeddableClassName = this.getTargetEmbeddable().getPersistentType().getName();
164
			IJavaProject javaProject = getJpaProject().getJavaProject();
165
			if (!JDTTools.classIsPublic(javaProject, targetEmbeddableClassName)
166
					|| !JDTTools.classHasPublicZeroArgConstructor(javaProject, targetEmbeddableClassName)) {
167
				messages.add(
168
					DefaultJpaValidationMessages.buildMessage(
169
						IMessage.HIGH_SEVERITY,
170
						JpaValidationMessages.EMBEDDED_ID_CLASS_SHOULD_BE_PUBLIC_AND_INCLUDE_ZERO_ARG_CONSTRUCTOR,
171
						EMPTY_STRING_ARRAY,
172
						this,
173
						this.getValidationTextRange(astRoot)
174
					)
175
				);
176
			}
177
		}
178
	}
179
	
180
	protected void validateTargeEmbeddableImplementsEqualsAndHashcode(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
181
		if (this.getTargetEmbeddable() != null) {
182
			String targetEmbeddableClassName = this.getTargetEmbeddable().getPersistentType().getName();
183
			IJavaProject javaProject = getJpaProject().getJavaProject();
184
			if (!JDTTools.typeNamedImplementsMethod(javaProject, targetEmbeddableClassName, "equals", new String[] {Object.class.getName()})
185
					|| !JDTTools.typeNamedImplementsMethod(javaProject, targetEmbeddableClassName, "hashCode", EMPTY_STRING_ARRAY)) {
186
				messages.add(
187
					DefaultJpaValidationMessages.buildMessage(
188
						IMessage.HIGH_SEVERITY,
189
						JpaValidationMessages.EMBEDDED_ID_CLASS_SHOULD_IMPLMENT_EQUALS_HASHCODE,
190
						EMPTY_STRING_ARRAY,
191
						this,
192
						this.getValidationTextRange(astRoot)
193
					)
194
				);
195
			}
196
		}
197
	}
198
	
199
	protected void validateMappedByRelationshipAndAttributeOverridesSpecified(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
113
		// [JPA 2.0] if the embedded id is mapped by a relationship, then any specified
200
		// [JPA 2.0] if the embedded id is mapped by a relationship, then any specified
114
		// attribute overrides are in error
201
		// attribute overrides are in error
115
		// (in JPA 1.0, this will obviously never be reached)
202
		// (in JPA 1.0, this will obviously never be reached)
Lines 124-130 Link Here
124
					this.attributeOverrideContainer.getValidationTextRange(astRoot)
211
					this.attributeOverrideContainer.getValidationTextRange(astRoot)
125
				)
212
				)
126
			);
213
			);
127
		}
214
		}		
128
	}
215
	}
129
216
130
	// ********** attribute override container owner *********
217
	// ********** attribute override container owner *********
(-)src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/GenericOrmEmbeddedIdMapping.java (-2 / +87 lines)
Lines 9-17 Link Here
9
 ******************************************************************************/
9
 ******************************************************************************/
10
package org.eclipse.jpt.jpa.core.internal.jpa1.context.orm;
10
package org.eclipse.jpt.jpa.core.internal.jpa1.context.orm;
11
11
12
import java.io.Serializable;
12
import java.util.Iterator;
13
import java.util.Iterator;
13
import java.util.List;
14
import java.util.List;
14
import java.util.Set;
15
import java.util.Set;
16
17
import org.eclipse.jdt.core.IJavaProject;
18
import org.eclipse.jpt.common.core.internal.utility.JDTTools;
15
import org.eclipse.jpt.common.utility.internal.CollectionTools;
19
import org.eclipse.jpt.common.utility.internal.CollectionTools;
16
import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator;
20
import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator;
17
import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator;
21
import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator;
Lines 121-127 Link Here
121
	@Override
125
	@Override
122
	public void validate(List<IMessage> messages, IReporter reporter) {
126
	public void validate(List<IMessage> messages, IReporter reporter) {
123
		super.validate(messages, reporter);
127
		super.validate(messages, reporter);
128
		validateMappedByRelationshipAndAttributeOverridesSpecified(messages, reporter);
129
		validateTargeEmbeddableImplementsEqualsAndHashcode(messages, reporter);
130
		validateTargetEmbeddableIsPublicWithZeroArgConstructor(messages, reporter);
131
		validateTargetEmbeddableImplementsSerializable(messages, reporter);
132
		validateNoRelationshipMappingsOnTargetEmbeddable(messages, reporter);
133
	}
134
	
135
	protected void validateNoRelationshipMappingsOnTargetEmbeddable(List<IMessage> messages, IReporter reporter) {
136
		if (this.getTargetEmbeddable() != null) {
137
			TypeMapping targetEmbeddableTypeMapping = this.getTargetEmbeddable().getPersistentType().getMapping();
138
			if (targetEmbeddableTypeMapping.getAllAttributeMappings(MappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY).iterator().hasNext()
139
					|| targetEmbeddableTypeMapping.getAllAttributeMappings(MappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY).iterator().hasNext()
140
					|| targetEmbeddableTypeMapping.getAllAttributeMappings(MappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY).iterator().hasNext()
141
					|| targetEmbeddableTypeMapping.getAllAttributeMappings(MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY).iterator().hasNext()) {
142
				messages.add(
143
					DefaultJpaValidationMessages.buildMessage(
144
						IMessage.HIGH_SEVERITY,
145
						JpaValidationMessages.EMBEDDED_ID_CLASS_SHOULD_NOT_CONTAIN_RELATIONSHIP_MAPPINGS,
146
						EMPTY_STRING_ARRAY,
147
						this,
148
						this.getValidationTextRange()
149
					)
150
				);				
151
			}
152
		}
153
	}
154
	
155
	protected void validateTargetEmbeddableImplementsSerializable(List<IMessage> messages, IReporter reporter) {
156
		if (this.getTargetEmbeddable() != null) {
157
			String targetEmbeddableClassName = this.getTargetEmbeddable().getPersistentType().getName();
158
			IJavaProject javaProject = getJpaProject().getJavaProject();
159
			if (!JDTTools.typeNamedImplementsInterfaceNamed(javaProject, targetEmbeddableClassName, Serializable.class.getName())) {
160
				messages.add(
161
					DefaultJpaValidationMessages.buildMessage(
162
						IMessage.HIGH_SEVERITY,
163
						JpaValidationMessages.EMBEDDED_ID_CLASS_SHOULD_IMPLEMENT_SERIALIZABLE,
164
						EMPTY_STRING_ARRAY,
165
						this,
166
						this.getValidationTextRange()
167
					)
168
				);
169
			}
170
		}
171
	}
172
	
173
	protected void validateTargetEmbeddableIsPublicWithZeroArgConstructor(List<IMessage> messages, IReporter reporter) {
174
		if (this.getTargetEmbeddable() != null) {
175
			String targetEmbeddableClassName = this.getTargetEmbeddable().getPersistentType().getName();
176
			IJavaProject javaProject = getJpaProject().getJavaProject();
177
			if (!JDTTools.classIsPublic(javaProject, targetEmbeddableClassName)
178
					|| !JDTTools.classHasPublicZeroArgConstructor(javaProject, targetEmbeddableClassName)) {
179
				messages.add(
180
					DefaultJpaValidationMessages.buildMessage(
181
						IMessage.HIGH_SEVERITY,
182
						JpaValidationMessages.EMBEDDED_ID_CLASS_SHOULD_BE_PUBLIC_AND_INCLUDE_ZERO_ARG_CONSTRUCTOR,
183
						EMPTY_STRING_ARRAY,
184
						this,
185
						this.getValidationTextRange()
186
					)
187
				);
188
			}
189
		}
190
	}
124
191
192
	protected void validateTargeEmbeddableImplementsEqualsAndHashcode(List<IMessage> messages, IReporter reporter) {
193
		if (this.getTargetEmbeddable() != null) {
194
			String targetEmbeddableClassName = this.getTargetEmbeddable().getPersistentType().getName();
195
			IJavaProject javaProject = getJpaProject().getJavaProject();
196
			if (!JDTTools.typeNamedImplementsMethod(javaProject, targetEmbeddableClassName, "equals", new String[] {Object.class.getName()})
197
					|| !JDTTools.typeNamedImplementsMethod(javaProject, targetEmbeddableClassName, "hashCode", EMPTY_STRING_ARRAY)) {
198
				messages.add(
199
					DefaultJpaValidationMessages.buildMessage(
200
						IMessage.HIGH_SEVERITY,
201
						JpaValidationMessages.EMBEDDED_ID_CLASS_SHOULD_IMPLMENT_EQUALS_HASHCODE,
202
						EMPTY_STRING_ARRAY,
203
						this,
204
						this.getValidationTextRange()
205
					)
206
				);
207
			}
208
		}
209
	}
210
	
211
	protected void validateMappedByRelationshipAndAttributeOverridesSpecified(List<IMessage> messages, IReporter reporter) {
125
		// [JPA 2.0] if the embedded id is mapped by a relationship, then any specified
212
		// [JPA 2.0] if the embedded id is mapped by a relationship, then any specified
126
		// attribute overrides are in error
213
		// attribute overrides are in error
127
		// (in JPA 1.0, this will obviously never be reached)
214
		// (in JPA 1.0, this will obviously never be reached)
Lines 138-145 Link Here
138
			);
225
			);
139
		}
226
		}
140
	}
227
	}
141
142
143
	// ********** attribute override container owner *********
228
	// ********** attribute override container owner *********
144
229
145
	protected class AttributeOverrideContainerOwner
230
	protected class AttributeOverrideContainerOwner
(-)src/org/eclipse/jpt/jpa/core/internal/validation/JpaValidationMessages.java (+5 lines)
Lines 56-61 Link Here
56
	public static final String TYPE_MAPPING_ID_CLASS_REQUIRED = "TYPE_MAPPING_ID_CLASS_REQUIRED";
56
	public static final String TYPE_MAPPING_ID_CLASS_REQUIRED = "TYPE_MAPPING_ID_CLASS_REQUIRED";
57
	public static final String TYPE_MAPPING_ID_CLASS_AND_EMBEDDED_ID_BOTH_USED = "TYPE_MAPPING_ID_CLASS_AND_EMBEDDED_ID_BOTH_USED";
57
	public static final String TYPE_MAPPING_ID_CLASS_AND_EMBEDDED_ID_BOTH_USED = "TYPE_MAPPING_ID_CLASS_AND_EMBEDDED_ID_BOTH_USED";
58
	public static final String TYPE_MAPPING_MULTIPLE_EMBEDDED_ID = "TYPE_MAPPING_MULTIPLE_EMBEDDED_ID";
58
	public static final String TYPE_MAPPING_MULTIPLE_EMBEDDED_ID = "TYPE_MAPPING_MULTIPLE_EMBEDDED_ID";
59
	public static final String TYPE_MAPPING_ID_AND_EMBEDDED_ID_BOTH_USED = "TYPE_MAPPING_ID_AND_EMBEDDED_ID_BOTH_USED";
59
	public static final String TYPE_MAPPING_ID_CLASS_WITH_MAPS_ID = "TYPE_MAPPING_ID_CLASS_WITH_MAPS_ID";
60
	public static final String TYPE_MAPPING_ID_CLASS_WITH_MAPS_ID = "TYPE_MAPPING_ID_CLASS_WITH_MAPS_ID";
60
	public static final String TYPE_MAPPING_MAPS_ID_ATTRIBUTE_TYPE_DOES_NOT_AGREE = "TYPE_MAPPING_MAPS_ID_ATTRIBUTE_TYPE_DOES_NOT_AGREE";
61
	public static final String TYPE_MAPPING_MAPS_ID_ATTRIBUTE_TYPE_DOES_NOT_AGREE = "TYPE_MAPPING_MAPS_ID_ATTRIBUTE_TYPE_DOES_NOT_AGREE";
61
	public static final String TYPE_MAPPING_ID_CLASS_ATTRIBUTE_NO_MATCH = "TYPE_MAPPING_ID_CLASS_ATTRIBUTE_NO_MATCH";
62
	public static final String TYPE_MAPPING_ID_CLASS_ATTRIBUTE_NO_MATCH = "TYPE_MAPPING_ID_CLASS_ATTRIBUTE_NO_MATCH";
Lines 94-99 Link Here
94
	public static final String ID_MAPPING_UNRESOLVED_GENERATOR_NAME = "ID_MAPPING_UNRESOLVED_GENERATOR_NAME";
95
	public static final String ID_MAPPING_UNRESOLVED_GENERATOR_NAME = "ID_MAPPING_UNRESOLVED_GENERATOR_NAME";
95
	public static final String ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_COLUMN_SPECIFIED = "ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_COLUMN_SPECIFIED";
96
	public static final String ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_COLUMN_SPECIFIED = "ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_COLUMN_SPECIFIED";
96
	public static final String EMBEDDED_ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_ATTRIBUTE_OVERRIDES_SPECIFIED = "EMBEDDED_ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_ATTRIBUTE_OVERRIDES_SPECIFIED";
97
	public static final String EMBEDDED_ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_ATTRIBUTE_OVERRIDES_SPECIFIED = "EMBEDDED_ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_ATTRIBUTE_OVERRIDES_SPECIFIED";
98
	public static final String EMBEDDED_ID_CLASS_SHOULD_IMPLMENT_EQUALS_HASHCODE = "EMBEDDED_ID_CLASS_SHOULD_IMPLMENT_EQUALS_HASHCODE";
99
	public static final String EMBEDDED_ID_CLASS_SHOULD_BE_PUBLIC_AND_INCLUDE_ZERO_ARG_CONSTRUCTOR="EMBEDDED_ID_CLASS_SHOULD_BE_PUBLIC_AND_INCLUDE_ZERO_ARG_CONSTRUCTOR";
100
	public static final String EMBEDDED_ID_CLASS_SHOULD_IMPLEMENT_SERIALIZABLE="EMBEDDED_ID_CLASS_SHOULD_IMPLEMENT_SERIALIZABLE";
101
	public static final String EMBEDDED_ID_CLASS_SHOULD_NOT_CONTAIN_RELATIONSHIP_MAPPINGS="EMBEDDED_ID_CLASS_SHOULD_NOT_CONTAIN_RELATIONSHIP_MAPPINGS";
97
	public static final String ATTRIBUTE_OVERRIDE_MAPPED_BY_RELATIONSHIP_AND_SPECIFIED = "ATTRIBUTE_OVERRIDE_MAPPED_BY_RELATIONSHIP_AND_SPECIFIED";
102
	public static final String ATTRIBUTE_OVERRIDE_MAPPED_BY_RELATIONSHIP_AND_SPECIFIED = "ATTRIBUTE_OVERRIDE_MAPPED_BY_RELATIONSHIP_AND_SPECIFIED";
98
	public static final String ATTRIBUTE_OVERRIDE_INVALID_NAME = "ATTRIBUTE_OVERRIDE_INVALID_NAME";
103
	public static final String ATTRIBUTE_OVERRIDE_INVALID_NAME = "ATTRIBUTE_OVERRIDE_INVALID_NAME";
99
	public static final String VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_INVALID_NAME = "VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_INVALID_NAME";
104
	public static final String VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_INVALID_NAME = "VIRTUAL_ATTRIBUTE_ATTRIBUTE_OVERRIDE_INVALID_NAME";

Return to bug 331480