1 /* Copyright 2004-2005 the original author or authors.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
15 package org
.codehaus
.groovy
.grails
.commons
;
18 import groovy
.lang
.GroovyObject
;
19 import org
.apache
.commons
.lang
.ClassUtils
;
20 import org
.apache
.commons
.lang
.StringUtils
;
21 import org
.apache
.commons
.logging
.Log
;
22 import org
.apache
.commons
.logging
.LogFactory
;
23 import org
.codehaus
.groovy
.grails
.exceptions
.GrailsDomainException
;
24 import org
.codehaus
.groovy
.grails
.exceptions
.InvalidPropertyException
;
25 import org
.springframework
.beans
.BeanUtils
;
26 import org
.springframework
.validation
.Validator
;
28 import java
.beans
.PropertyDescriptor
;
29 import java
.beans
.IntrospectionException
;
30 import java
.lang
.reflect
.Modifier
;
34 * @author Graeme Rocher
37 public class DefaultGrailsDomainClass
extends AbstractGrailsClass
implements GrailsDomainClass
{
39 private static final Log LOG
= LogFactory
.getLog(DefaultGrailsDomainClass
.class);
42 private GrailsDomainClassProperty identifier
;
43 private GrailsDomainClassProperty version
;
44 private GrailsDomainClassProperty
[] properties
;
45 private GrailsDomainClassProperty
[] persistantProperties
;
46 private Map propertyMap
;
47 private Map relationshipMap
;
49 private Map constraints
= new HashMap();
51 private Validator validator
;
52 private String mappingStrategy
= GrailsDomainClass
.GORM
;
53 private List owners
= new ArrayList();
54 private boolean root
= true;
55 private Set subClasses
= new HashSet();
56 private Collection embedded
;
58 public DefaultGrailsDomainClass(Class clazz
) {
60 PropertyDescriptor
[] propertyDescriptors
= getReference().getPropertyDescriptors();
62 if(!clazz
.getSuperclass().equals( GroovyObject
.class ) &&
63 !clazz
.getSuperclass().equals(Object
.class) &&
64 !Modifier
.isAbstract(clazz
.getSuperclass().getModifiers())) {
67 this.propertyMap
= new LinkedHashMap();
68 this.relationshipMap
= getAssociationMap();
69 this.embedded
= getEmbeddedList();
71 // get mapping strategy by setting
72 if(getPropertyOrStaticPropertyOrFieldValue(GrailsDomainClassProperty
.MAPPING_STRATEGY
, String
.class) != null)
73 this.mappingStrategy
= (String
)getPropertyOrStaticPropertyOrFieldValue(GrailsDomainClassProperty
.MAPPING_STRATEGY
, String
.class);
75 // get any mappedBy settings
76 this.mappedBy
= (Map
)getPropertyOrStaticPropertyOrFieldValue(GrailsDomainClassProperty
.MAPPED_BY
, Map
.class);
77 if(this.mappedBy
== null)this.mappedBy
= Collections
.EMPTY_MAP
;
79 // establish the owners of relationships
80 establishRelationshipOwners();
82 // First go through the properties of the class and create domain properties
83 // populating into a map
84 populateDomainClassProperties(propertyDescriptors
);
86 // if no identifier property throw exception
87 if(this.identifier
== null) {
88 throw new GrailsDomainException("Identity property not found, but required in domain class ["+getFullName()+"]" );
90 // if no version property throw exception
91 if(this.version
== null) {
92 throw new GrailsDomainException("Version property not found, but required in domain class ["+getFullName()+"]" );
94 // set properties from map values
95 this.properties
= (GrailsDomainClassProperty
[])this.propertyMap
.values().toArray( new GrailsDomainClassProperty
[this.propertyMap
.size()] );
97 // establish relationships
98 establishRelationships();
100 // set persistant properties
101 establishPersistentProperties();
102 // process the constraints
104 this.constraints
= GrailsDomainConfigurationUtil
.evaluateConstraints(getReference().getWrappedInstance(), this.persistantProperties
);
105 } catch (IntrospectionException e
) {
106 LOG
.error("Error reading class ["+getClazz()+"] constraints: " +e
.getMessage(), e
);
113 public boolean hasSubClasses() {
114 return getSubClasses().size() > 0;
120 * calculates the persistent properties from the evaluated properties
122 private void establishPersistentProperties() {
123 Collection tempList
= new ArrayList();
124 for(Iterator i
= this.propertyMap
.values().iterator();i
.hasNext();) {
125 GrailsDomainClassProperty currentProp
= (GrailsDomainClassProperty
)i
.next();
126 if(currentProp
.getType() != Object
.class && currentProp
.isPersistent() && !currentProp
.isIdentity() && !currentProp
.getName().equals( GrailsDomainClassProperty
.VERSION
)) {
127 tempList
.add(currentProp
);
130 this.persistantProperties
= (GrailsDomainClassProperty
[])tempList
.toArray( new GrailsDomainClassProperty
[tempList
.size()]);
134 * Evaluates the belongsTo property to find out who owns who
136 private void establishRelationshipOwners() {
137 Class belongsTo
= (Class
)getPropertyOrStaticPropertyOrFieldValue(GrailsDomainClassProperty
.BELONGS_TO
, Class
.class);
138 if(belongsTo
== null) {
139 List ownersProp
= (List
)getPropertyOrStaticPropertyOrFieldValue(GrailsDomainClassProperty
.BELONGS_TO
, List
.class);
140 if(ownersProp
!= null) {
141 this.owners
= ownersProp
;
144 Map ownersMap
= (Map
)getPropertyOrStaticPropertyOrFieldValue(GrailsDomainClassProperty
.BELONGS_TO
, Map
.class);
145 if(ownersMap
!=null) {
146 this.owners
= new ArrayList(ownersMap
.values());
151 this.owners
= new ArrayList();
152 this.owners
.add(belongsTo
);
157 * Populates the domain class properties map
159 * @param propertyDescriptors The property descriptors
161 private void populateDomainClassProperties(PropertyDescriptor
[] propertyDescriptors
) {
162 for(int i
= 0; i
< propertyDescriptors
.length
; i
++) {
164 PropertyDescriptor descriptor
= propertyDescriptors
[i
];
165 // ignore certain properties
166 if(GrailsDomainConfigurationUtil
.isNotConfigurational(descriptor
) ) {
169 GrailsDomainClassProperty property
= new DefaultGrailsDomainClassProperty(this, descriptor
);
170 this.propertyMap
.put(property
.getName(), property
);
172 if(property
.isIdentity()) {
173 this.identifier
= property
;
175 else if(property
.getName().equals( GrailsDomainClassProperty
.VERSION
)) {
176 this.version
= property
;
184 * Retrieves the association map
186 public Map
getAssociationMap() {
187 if(this.relationshipMap
== null) {
188 relationshipMap
= (Map
)getPropertyOrStaticPropertyOrFieldValue( GrailsDomainClassProperty
.HAS_MANY
, Map
.class );
189 if(relationshipMap
== null)
190 this.relationshipMap
= new HashMap();
192 Class theClass
= getClazz();
193 while(theClass
!= Object
.class) {
194 theClass
= theClass
.getSuperclass();
195 Map superRelationshipMap
= (Map
)GrailsClassUtils
.getStaticPropertyValue(theClass
, GrailsDomainClassProperty
.HAS_MANY
);
196 if(superRelationshipMap
!= null && !superRelationshipMap
.equals(relationshipMap
)) {
197 relationshipMap
.putAll(superRelationshipMap
);
201 return this.relationshipMap
;
205 * Retrieves the list of known embedded component types
207 * @return A list of embedded components
209 private Collection
getEmbeddedList() {
210 Object potentialList
= GrailsClassUtils
.getStaticPropertyValue(getClazz(), GrailsDomainClassProperty
.EMBEDDED
);
211 if(potentialList
instanceof Collection
) {
212 return (Collection
)potentialList
;
214 return Collections
.EMPTY_LIST
;
219 * Calculates the relationship type based other types referenced
222 private void establishRelationships() {
223 for(Iterator i
= this.propertyMap
.values().iterator();i
.hasNext(); ) {
224 DefaultGrailsDomainClassProperty currentProp
= (DefaultGrailsDomainClassProperty
)i
.next();
225 Class currentPropType
= currentProp
.getType();
226 // establish if the property is a one-to-many
227 // if it is a Set and there are relationships defined
228 // and it is defined as persistent
229 if( Collection
.class.isAssignableFrom(currentPropType
) || Map
.class.isAssignableFrom(currentPropType
) &&
230 currentProp
.isPersistent() ) {
232 establishRelationshipForCollection( currentProp
);
234 // otherwise if the type is a domain class establish relationship
235 else if(DomainClassArtefactHandler
.isDomainClass(currentPropType
) &&
236 currentProp
.isPersistent()) {
238 establishDomainClassRelationship( currentProp
);
240 else if(!GrailsDomainConfigurationUtil
.isBasicType(currentProp
)) {
241 establishDomainClassRelationship( currentProp
);
249 * Establishes a relationship for a java.util.Set
251 * @param property The collection property
253 private void establishRelationshipForCollection(DefaultGrailsDomainClassProperty property
) {
254 // is it a relationship
255 Class relatedClassType
= getRelatedClassType( property
.getName() );
258 if(relatedClassType
!= null) {
259 // set the referenced type in the property
260 property
.setReferencedPropertyType(relatedClassType
);
262 // if the related type is a domain class
263 // then figure out what kind of relationship it is
264 if(DomainClassArtefactHandler
.isDomainClass(relatedClassType
)) {
267 // check the relationship defined in the referenced type
268 // if it is also a Set/domain class etc.
269 Map relatedClassRelationships
= GrailsDomainConfigurationUtil
.getAssociationMap(relatedClassType
);
270 Class relatedClassPropertyType
= null;
272 // First check whether there is an explicit relationship
273 // mapping for this property (as provided by "mappedBy").
274 String mappingProperty
= (String
)this.mappedBy
.get(property
.getName());
275 if(!StringUtils
.isBlank(mappingProperty
)) {
276 // First find the specified property on the related
277 // class, if it exists.
278 PropertyDescriptor pd
= findProperty(GrailsClassUtils
.getPropertiesOfType(relatedClassType
, getClazz()), mappingProperty
);
280 // If a property of the required type does not exist,
281 // search for any collection properties on the related
283 if(pd
== null) pd
= findProperty(GrailsClassUtils
.getPropertiesAssignableToType(relatedClassType
, Collection
.class), mappingProperty
);
285 // We've run out of options. The given "mappedBy"
286 // setting is invalid.
288 throw new GrailsDomainException("Non-existent mapping property ["+mappingProperty
+"] specified for property ["+property
.getName()+"] in class ["+getClazz()+"]");
290 // Tie the properties together.
291 relatedClassPropertyType
= pd
.getPropertyType();
292 property
.setReferencePropertyName(pd
.getName());
295 // if the related type has a relationships map it may be a many-to-many
296 // figure out if there is a many-to-many relationship defined
297 if( isRelationshipManyToMany(property
, relatedClassType
, relatedClassRelationships
)) {
298 String relatedClassPropertyName
= null;
299 // retrieve the relationship property
300 for(Iterator i
= relatedClassRelationships
.keySet().iterator();i
.hasNext();) {
301 String currentKey
= (String
)i
.next();
302 Class currentClass
= (Class
) relatedClassRelationships
.get( currentKey
);
303 if(currentClass
.isAssignableFrom(getClazz())) {
304 relatedClassPropertyName
= currentKey
;
309 // if there is one defined get the type
310 if(relatedClassPropertyName
!= null) {
311 relatedClassPropertyType
= GrailsClassUtils
.getPropertyType( relatedClassType
, relatedClassPropertyName
);
314 // otherwise figure out if there is a one-to-many relationship by retrieving any properties that are of the related type
315 // if there is more than one property then (for the moment) ignore the relationship
316 if(relatedClassPropertyType
== null) {
317 PropertyDescriptor
[] descriptors
= GrailsClassUtils
.getPropertiesOfType(relatedClassType
, getClazz());
319 if(descriptors
.length
== 1) {
320 relatedClassPropertyType
= descriptors
[0].getPropertyType();
321 property
.setReferencePropertyName(descriptors
[0].getName());
323 else if(descriptors
.length
> 1) {
324 // try now to use the class name by convention
325 String classPropertyName
= getPropertyName();
326 PropertyDescriptor pd
= findProperty(descriptors
, classPropertyName
);
328 throw new GrailsDomainException("Property ["+property
.getName()+"] in class ["+getClazz()+"] is a bidirectional one-to-many with two possible properties on the inverse side. "+
329 "Either name one of the properties on other side of the relationship ["+classPropertyName
+"] or use the 'mappedBy' static to define the property " +
330 "that the relationship is mapped with. Example: static mappedBy = ["+property
.getName()+":'myprop']");
333 relatedClassPropertyType
= pd
.getPropertyType();
334 property
.setReferencePropertyName(pd
.getName());
339 establishRelationshipForSetToType(property
,relatedClassPropertyType
);
340 // if its a many-to-many figure out the owning side of the relationship
341 if(property
.isManyToMany()) {
342 establishOwnerOfManyToMany(property
, relatedClassType
);
345 // otherwise set it to not persistent as you can't persist
346 // relationships to non-domain classes
348 property
.setPersistant(false);
351 else if(!Map
.class.isAssignableFrom(property
.getType())) {
352 // no relationship defined for set.
353 // set not persistent
354 property
.setPersistant(false);
360 * Finds a property type is an array of descriptors for the given property name
362 * @param descriptors The descriptors
363 * @param propertyName The property name
364 * @return The Class or null
366 private PropertyDescriptor
findProperty(PropertyDescriptor
[] descriptors
, String propertyName
) {
367 PropertyDescriptor d
= null;
368 for (int i
= 0; i
< descriptors
.length
; i
++) {
369 PropertyDescriptor descriptor
= descriptors
[i
];
370 if(descriptor
.getName().equals(propertyName
)) {
379 * Find out if the relationship is a many-to-many
381 * @param property The property
382 * @param relatedClassType The related type
383 * @param relatedClassRelationships The related types relationships
384 * @return True if the relationship is a many-to-many
386 private boolean isRelationshipManyToMany(DefaultGrailsDomainClassProperty property
, Class relatedClassType
, Map relatedClassRelationships
) {
387 return relatedClassRelationships
!= null &&
388 !relatedClassRelationships
.isEmpty() &&
389 !relatedClassType
.equals(property
.getDomainClass().getClazz());
393 * Inspects a related classes' ownership settings against this properties class' ownership
394 * settings to find out who owns a many-to-many relationship
396 * @param property The property
397 * @param relatedClassType The related type
399 private void establishOwnerOfManyToMany(DefaultGrailsDomainClassProperty property
, Class relatedClassType
) {
400 Object related
= BeanUtils
.instantiateClass(relatedClassType
);
401 Object relatedBelongsTo
= GrailsClassUtils
.getPropertyOrStaticPropertyOrFieldValue(related
, GrailsDomainClassProperty
.BELONGS_TO
);
402 boolean owningSide
= false;
403 boolean relatedOwner
= this.owners
.contains(relatedClassType
);
404 final Class propertyClass
= property
.getDomainClass().getClazz();
405 if(relatedBelongsTo
instanceof Collection
) {
406 owningSide
= ((Collection
)relatedBelongsTo
).contains(propertyClass
);
408 else if (relatedBelongsTo
!= null) {
409 owningSide
= relatedBelongsTo
.equals(propertyClass
);
411 property
.setOwningSide(owningSide
);
412 if(relatedOwner
&& property
.isOwningSide()) {
413 throw new GrailsDomainException("Domain classes ["+propertyClass
+"] and ["+relatedClassType
+"] cannot own each other in a many-to-many relationship. Both contain belongsTo definitions that reference each other.");
415 else if(!relatedOwner
&& !property
.isOwningSide()) {
416 throw new GrailsDomainException("No owner defined between domain classes ["+propertyClass
+"] and ["+relatedClassType
+"] in a many-to-many relationship. Example: def belongsTo = "+relatedClassType
.getName());
421 * Establishes whether the relationship is a bi-directional or uni-directional one-to-many
422 * and applies the appropriate settings to the specified property
424 * @param property The property to apply settings to
425 * @param relatedClassPropertyType The related type
427 private void establishRelationshipForSetToType(DefaultGrailsDomainClassProperty property
, Class relatedClassPropertyType
) {
429 if(relatedClassPropertyType
== null) {
430 // uni-directional one-to-many
431 property
.setOneToMany(true);
432 property
.setBidirectional(false);
434 else if( Collection
.class.isAssignableFrom(relatedClassPropertyType
) ){
436 property
.setManyToMany(true);
437 property
.setBidirectional(true);
439 else if(DomainClassArtefactHandler
.isDomainClass(relatedClassPropertyType
)) {
440 // bi-directional one-to-many
441 property
.setOneToMany( true );
442 property
.setBidirectional( true );
448 * Establish relationship with related domain class
450 * @param property Establishes a relationship between this class and the domain class property
452 private void establishDomainClassRelationship(DefaultGrailsDomainClassProperty property
) {
453 Class propType
= property
.getType();
454 if(embedded
.contains(property
.getName())) {
455 property
.setEmbedded(true);
459 // establish relationship to type
460 Map relatedClassRelationships
= GrailsDomainConfigurationUtil
.getAssociationMap(propType
);
461 Map mappedBy
= GrailsDomainConfigurationUtil
.getMappedByMap(propType
);
464 Class relatedClassPropertyType
= null;
466 // if there is a relationships map use that to find out
467 // whether it is mapped to a Set
468 if( relatedClassRelationships
!= null &&
469 !relatedClassRelationships
.isEmpty() ) {
472 String relatedClassPropertyName
= findOneToManyThatMatchesType(property
, relatedClassRelationships
);
473 PropertyDescriptor
[] descriptors
= GrailsClassUtils
.getPropertiesOfType(getClazz(), property
.getType());
475 // if there is only one property on many-to-one side of the relationship then
476 // try to establish if it is bidirectional
477 if(descriptors
.length
== 1 && isNotMappedToDifferentProperty(property
,relatedClassPropertyName
, mappedBy
)) {
478 if(!StringUtils
.isBlank(relatedClassPropertyName
)) {
479 property
.setReferencePropertyName(relatedClassPropertyName
);
480 // get the type of the property
481 relatedClassPropertyType
= GrailsClassUtils
.getPropertyType( propType
, relatedClassPropertyName
);
484 // if there is more than one property on the many-to-one side then we need to either
485 // find out if there is a mappedBy property or whether a convention is used to decide
486 // on the mapping property
487 else if(descriptors
.length
> 1) {
488 if(mappedBy
.containsValue(property
.getName())) {
489 for (Iterator i
= mappedBy
.keySet().iterator(); i
.hasNext();) {
490 String mappedByPropertyName
= (String
) i
.next();
491 if(property
.getName().equals(mappedBy
.get(mappedByPropertyName
))) {
492 Class mappedByRelatedType
= (Class
)relatedClassRelationships
.get(mappedByPropertyName
);
493 if(mappedByRelatedType
!= null && propType
.isAssignableFrom(mappedByRelatedType
))
494 relatedClassPropertyType
= GrailsClassUtils
.getPropertyType( propType
, mappedByPropertyName
);
499 String classNameAsProperty
= GrailsClassUtils
.getPropertyName(propType
);
500 if(property
.getName().equals(classNameAsProperty
) && !mappedBy
.containsKey(relatedClassPropertyName
)) {
501 relatedClassPropertyType
= GrailsClassUtils
.getPropertyType( propType
, relatedClassPropertyName
);
506 // otherwise retrieve all the properties of the type from the associated class
507 if(relatedClassPropertyType
== null) {
508 PropertyDescriptor
[] descriptors
= GrailsClassUtils
.getPropertiesOfType(propType
, getClazz());
510 // if there is only one then the association is established
511 if(descriptors
.length
== 1) {
512 relatedClassPropertyType
= descriptors
[0].getPropertyType();
517 // establish relationship based on this type
518 establishDomainClassRelationshipToType( property
, relatedClassPropertyType
);
521 private boolean isNotMappedToDifferentProperty(GrailsDomainClassProperty property
, String relatedClassPropertyName
, Map mappedBy
) {
522 String mappedByForRelation
= (String
)mappedBy
.get(relatedClassPropertyName
);
523 if(mappedByForRelation
== null) return true;
524 else if(!property
.getName().equals(mappedByForRelation
)) return false;
528 private String
findOneToManyThatMatchesType(DefaultGrailsDomainClassProperty property
, Map relatedClassRelationships
) {
529 String relatedClassPropertyName
= null;
530 for(Iterator i
= relatedClassRelationships
.keySet().iterator();i
.hasNext();) {
531 String currentKey
= (String
)i
.next();
532 Class currentClass
= (Class
)relatedClassRelationships
.get( currentKey
);
534 if(property
.getDomainClass().getClazz().getName().equals( currentClass
.getName() )) {
535 relatedClassPropertyName
= currentKey
;
540 return relatedClassPropertyName
;
543 private void establishDomainClassRelationshipToType(DefaultGrailsDomainClassProperty property
, Class relatedClassPropertyType
) {
544 // uni-directional one-to-one
545 if(relatedClassPropertyType
== null) {
546 property
.setOneToOne(true);
547 property
.setBidirectional(false);
549 // bi-directional many-to-one
550 else if(Collection
.class.isAssignableFrom(relatedClassPropertyType
)||Map
.class.isAssignableFrom(relatedClassPropertyType
)) {
551 property
.setManyToOne(true);
552 property
.setBidirectional(true);
554 // bi-directional one-to-one
555 else if(DomainClassArtefactHandler
.isDomainClass(relatedClassPropertyType
)) {
556 property
.setOneToOne(true);
557 if(!getClazz().equals(relatedClassPropertyType
))
558 property
.setBidirectional(true);
563 public boolean isOwningClass(Class domainClass
) {
564 return this.owners
.contains(domainClass
);
568 * @see org.codehaus.groovy.grails.domain.GrailsDomainClass#getProperties()
570 public GrailsDomainClassProperty
[] getProperties() {
571 return this.properties
;
575 * @see org.codehaus.groovy.grails.domain.GrailsDomainClass#getIdentifier()
577 public GrailsDomainClassProperty
getIdentifier() {
578 return this.identifier
;
582 * @see org.codehaus.groovy.grails.domain.GrailsDomainClass#getVersion()
584 public GrailsDomainClassProperty
getVersion() {
589 * @see org.codehaus.groovy.grails.commons.GrailsDomainClass#getPersistantProperties()
592 public GrailsDomainClassProperty
[] getPersistantProperties() {
593 return this.persistantProperties
;
596 public GrailsDomainClassProperty
[] getPersistentProperties() {
597 return this.persistantProperties
;
601 * @see org.codehaus.groovy.grails.domain.GrailsDomainClass#getPropertyByName(java.lang.String)
603 public GrailsDomainClassProperty
getPropertyByName(String name
) {
604 if(this.propertyMap
.containsKey(name
)) {
605 return (GrailsDomainClassProperty
)this.propertyMap
.get(name
);
608 throw new InvalidPropertyException("No property found for name ["+name
+"] for class ["+getClazz()+"]");
612 * @see org.codehaus.groovy.grails.domain.GrailsDomainClass#getFieldName(java.lang.String)
614 public String
getFieldName(String propertyName
) {
615 return getPropertyByName(propertyName
).getFieldName();
619 * @see org.codehaus.groovy.grails.commons.AbstractGrailsClass#getName()
621 public String
getName() {
622 return ClassUtils
.getShortClassName(super.getName());
625 * @see org.codehaus.groovy.grails.domain.GrailsDomainClass#isOneToMany(java.lang.String)
627 public boolean isOneToMany(String propertyName
) {
628 return getPropertyByName(propertyName
).isOneToMany();
631 * @see org.codehaus.groovy.grails.domain.GrailsDomainClass#isManyToOne(java.lang.String)
633 public boolean isManyToOne(String propertyName
) {
634 return getPropertyByName(propertyName
).isManyToOne();
637 protected Object
getPropertyOrStaticPropertyOrFieldValue(String name
, Class type
) {
638 return super.getPropertyOrStaticPropertyOrFieldValue(name
,type
);
641 * @see org.codehaus.groovy.grails.commons.GrailsDomainClass#getRelationshipType(java.lang.String)
643 public Class
getRelatedClassType(String propertyName
) {
644 return (Class
)this.relationshipMap
.get(propertyName
);
648 * @see org.codehaus.groovy.grails.commons.GrailsDomainClass#getPropertyName()
650 public String
getPropertyName() {
651 return GrailsClassUtils
.getPropertyNameRepresentation(getClazz());
655 * @see org.codehaus.groovy.grails.commons.GrailsDomainClass#isBidirectional()
657 public boolean isBidirectional(String propertyName
) {
658 return getPropertyByName(propertyName
).isBidirectional();
662 * @see org.codehaus.groovy.grails.commons.GrailsDomainClass#getConstraints()
664 public Map
getConstrainedProperties() {
665 return Collections
.unmodifiableMap(this.constraints
);
668 * @see org.codehaus.groovy.grails.commons.GrailsDomainClass#getValidator()
670 public Validator
getValidator() {
671 return this.validator
;
675 * @see org.codehaus.groovy.grails.commons.GrailsDomainClass#setValidator(Validator validator)
677 public void setValidator(Validator validator
) {
678 this.validator
= validator
;
682 * @see org.codehaus.groovy.grails.commons.GrailsDomainClass#getMappedBy()
684 public String
getMappingStrategy() {
685 return this.mappingStrategy
;
688 public boolean isRoot() {
692 public Set
getSubClasses() {
693 return this.subClasses
;
696 public void refreshConstraints() {
698 this.constraints
= GrailsDomainConfigurationUtil
.evaluateConstraints(getReference().getWrappedInstance(), this.persistantProperties
);
699 } catch (IntrospectionException e
) {
700 LOG
.error("Error reading class ["+getClazz()+"] constraints: " +e
.getMessage(), e
);
704 public Map
getMappedBy() {
708 public boolean hasPersistentProperty(String propertyName
) {
709 for (int i
= 0; i
< persistantProperties
.length
; i
++) {
710 GrailsDomainClassProperty persistantProperty
= persistantProperties
[i
];
711 if(persistantProperty
.getName().equals(propertyName
)) return true;
716 public void setMappingStrategy(String strategy
) {
717 this.mappingStrategy
= strategy
;