KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > engine > Nullability


1 //$Id: Nullability.java,v 1.12 2005/07/20 07:16:17 oneovthafew Exp $
2
package org.hibernate.engine;
3
4 import java.util.Iterator JavaDoc;
5
6 import org.hibernate.HibernateException;
7 import org.hibernate.PropertyValueException;
8 import org.hibernate.intercept.LazyPropertyInitializer;
9 import org.hibernate.persister.entity.EntityPersister;
10 import org.hibernate.type.AbstractComponentType;
11 import org.hibernate.type.CollectionType;
12 import org.hibernate.type.Type;
13
14 /**
15  * Implements the algorithm for validating property values
16  * for illegal null values
17  * @author Gavin King
18  */

19 public final class Nullability {
20     
21     private final SessionImplementor session;
22     
23     public Nullability(SessionImplementor session) {
24         this.session = session;
25     }
26     /**
27      * Check nullability of the class persister properties
28      *
29      * @param values entity properties
30      * @param persister class persister
31      * @param isUpdate wether it is intended to be updated or saved
32      * @throws org.hibernate.PropertyValueException Break the nullability of one property
33      * @throws HibernateException error while getting Component values
34      */

35     public void checkNullability(
36             final Object JavaDoc[] values,
37             final EntityPersister persister,
38             final boolean isUpdate)
39     throws PropertyValueException, HibernateException {
40
41         /*
42           * Algorithm
43           * Check for any level one nullability breaks
44           * Look at non null components to
45           * recursively check next level of nullability breaks
46           * Look at Collections contraining component to
47           * recursively check next level of nullability breaks
48           *
49           *
50           * In the previous implementation, not-null stuffs where checked
51           * filtering by level one only updateable
52           * or insertable columns. So setting a sub component as update="false"
53           * has no effect on not-null check if the main component had good checkeability
54           * In this implementation, we keep this feature.
55           * However, I never see any documentation mentioning that, but it's for
56           * sure a limitation.
57           */

58
59         final boolean[] nullability = persister.getPropertyNullability();
60         final boolean[] checkability = isUpdate ?
61             persister.getPropertyUpdateability() :
62             persister.getPropertyInsertability();
63         final Type[] propertyTypes = persister.getPropertyTypes();
64
65         for ( int i = 0; i < values.length; i++ ) {
66             
67             if ( checkability[i] && values[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
68                 final Object JavaDoc value = values[i];
69                 if ( !nullability[i] && value == null ) {
70                     
71                     //check basic level one nullablilty
72
throw new PropertyValueException(
73                             "not-null property references a null or transient value",
74                             persister.getEntityName(),
75                             persister.getPropertyNames()[i]
76                         );
77                     
78                 }
79                 else if ( value != null ) {
80                     
81                     //values is not null and is checkable, we'll look deeper
82
String JavaDoc breakProperties = checkSubElementsNullability( propertyTypes[i], value );
83                     if ( breakProperties != null ) {
84                         throw new PropertyValueException(
85                             "not-null property references a null or transient value",
86                             persister.getEntityName(),
87                             buildPropertyPath( persister.getPropertyNames()[i], breakProperties )
88                         );
89                     }
90                     
91                 }
92             }
93             
94         }
95     }
96
97     /**
98      * check sub elements-nullability. Returns property path that break
99      * nullability or null if none
100      *
101      * @param propertyType type to check
102      * @param value value to check
103      *
104      * @return property path
105      * @throws HibernateException error while getting subcomponent values
106      */

107     private String JavaDoc checkSubElementsNullability(final Type propertyType, final Object JavaDoc value)
108     throws HibernateException {
109         //for non null args, check for components and elements containing components
110
if ( propertyType.isComponentType() ) {
111             return checkComponentNullability( value, (AbstractComponentType) propertyType );
112         }
113         else if ( propertyType.isCollectionType() ) {
114
115             //persistent collections may have components
116
CollectionType collectionType = (CollectionType) propertyType;
117             Type collectionElementType = collectionType.getElementType( session.getFactory() );
118             if ( collectionElementType.isComponentType() ) {
119                 //check for all components values in the collection
120

121                 AbstractComponentType componentType = (AbstractComponentType) collectionElementType;
122                 Iterator JavaDoc iter = CascadingAction.getLoadedElementsIterator(session, collectionType, value);
123                 while ( iter.hasNext() ) {
124                     Object JavaDoc compValue = iter.next();
125                     if (compValue != null) {
126                         return checkComponentNullability(compValue, componentType);
127                     }
128                 }
129             }
130         }
131         return null;
132     }
133
134     /**
135      * check component nullability. Returns property path that break
136      * nullability or null if none
137      *
138      * @param value component properties
139      * @param compType component not-nullable type
140      *
141      * @return property path
142      * @throws HibernateException error while getting subcomponent values
143      */

144     private String JavaDoc checkComponentNullability(final Object JavaDoc value, final AbstractComponentType compType)
145     throws HibernateException {
146         /* will check current level if some of them are not null
147          * or sublevels if they exist
148          */

149         boolean[] nullability = compType.getPropertyNullability();
150         if ( nullability!=null ) {
151             //do the test
152
final Object JavaDoc[] values = compType.getPropertyValues( value, session.getEntityMode() );
153             final Type[] propertyTypes = compType.getSubtypes();
154             for ( int i=0; i<values.length; i++ ) {
155                 final Object JavaDoc subvalue = values[i];
156                 if ( !nullability[i] && subvalue==null ) {
157                     return compType.getPropertyNames()[i];
158                 }
159                 else if ( subvalue != null ) {
160                     String JavaDoc breakProperties = checkSubElementsNullability( propertyTypes[i], subvalue );
161                     if ( breakProperties != null ) {
162                         return buildPropertyPath( compType.getPropertyNames()[i], breakProperties );
163                     }
164                 }
165             }
166         }
167         return null;
168     }
169
170     /**
171      * Return a well formed property path.
172      * Basicaly, it will return parent.child
173      *
174      * @param parent parent in path
175      * @param child child in path
176      * @return parent-child path
177      */

178     private static String JavaDoc buildPropertyPath(String JavaDoc parent, String JavaDoc child) {
179         return new StringBuffer JavaDoc( parent.length() + child.length() + 1 )
180             .append(parent).append('.').append(child).toString();
181     }
182
183 }
184
Popular Tags