KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > type > ComponentType


1 //$Id: ComponentType.java,v 1.35 2005/07/19 18:17:14 oneovthafew Exp $
2
package org.hibernate.type;
3
4 import java.io.Serializable JavaDoc;
5 import java.lang.reflect.Method JavaDoc;
6 import java.sql.PreparedStatement JavaDoc;
7 import java.sql.ResultSet JavaDoc;
8 import java.sql.SQLException JavaDoc;
9 import java.util.HashMap JavaDoc;
10 import java.util.Map JavaDoc;
11
12 import org.dom4j.Element;
13 import org.dom4j.Node;
14 import org.hibernate.EntityMode;
15 import org.hibernate.FetchMode;
16 import org.hibernate.HibernateException;
17 import org.hibernate.MappingException;
18 import org.hibernate.engine.CascadeStyle;
19 import org.hibernate.engine.Mapping;
20 import org.hibernate.engine.SessionFactoryImplementor;
21 import org.hibernate.engine.SessionImplementor;
22 import org.hibernate.tuple.ComponentTuplizer;
23 import org.hibernate.tuple.TuplizerLookup;
24 import org.hibernate.util.ArrayHelper;
25 import org.hibernate.util.StringHelper;
26
27 /**
28  * Handles "component" mappings
29  *
30  * @author Gavin King
31  */

32 public class ComponentType extends AbstractType implements AbstractComponentType {
33
34     private final Type[] propertyTypes;
35     private final String JavaDoc[] propertyNames;
36     private final boolean[] propertyNullability;
37     protected final int propertySpan;
38     private final CascadeStyle[] cascade;
39     private final FetchMode[] joinedFetch;
40     private final boolean isKey;
41     
42     protected TuplizerLookup tuplizers;
43
44     public int[] sqlTypes(Mapping mapping) throws MappingException {
45         //Not called at runtime so doesn't matter if its slow :)
46
int[] sqlTypes = new int[getColumnSpan( mapping )];
47         int n = 0;
48         for ( int i = 0; i < propertySpan; i++ ) {
49             int[] subtypes = propertyTypes[i].sqlTypes( mapping );
50             for ( int j = 0; j < subtypes.length; j++ ) {
51                 sqlTypes[n++] = subtypes[j];
52             }
53         }
54         return sqlTypes;
55     }
56
57     public int getColumnSpan(Mapping mapping) throws MappingException {
58         int span = 0;
59         for ( int i = 0; i < propertySpan; i++ ) {
60             span += propertyTypes[i].getColumnSpan( mapping );
61         }
62         return span;
63     }
64
65     public ComponentType(
66             final String JavaDoc[] propertyNames,
67             final Type[] propertyTypes,
68             final boolean[] nullabilities,
69             final FetchMode[] joinedFetch,
70             final CascadeStyle[] cascade,
71             final boolean key,
72             final TuplizerLookup tuplizers)
73     throws MappingException {
74
75         this.propertyTypes = propertyTypes;
76         this.propertyNullability = nullabilities;
77         this.propertyNames = propertyNames;
78         this.cascade = cascade;
79         this.joinedFetch = joinedFetch;
80         isKey = key;
81         propertySpan = propertyTypes.length;
82         this.tuplizers = tuplizers;
83     }
84
85     public final boolean isComponentType() {
86         return true;
87     }
88
89     public Class JavaDoc getReturnedClass() {
90         return tuplizers.getTuplizer(EntityMode.POJO).getMappedClass(); //TODO
91
}
92
93     public boolean isSame(Object JavaDoc x, Object JavaDoc y, EntityMode entityMode) throws HibernateException {
94         if ( x == y ) return true;
95         if ( x == null || y == null ) return false;
96         Object JavaDoc[] xvalues = getPropertyValues(x, entityMode);
97         Object JavaDoc[] yvalues = getPropertyValues(y, entityMode);
98         for ( int i = 0; i < propertySpan; i++ ) {
99             if ( !propertyTypes[i].isSame( xvalues[i], yvalues[i], entityMode ) ) {
100                 return false;
101             }
102         }
103         return true;
104     }
105
106     public boolean isEqual(Object JavaDoc x, Object JavaDoc y, EntityMode entityMode)
107     throws HibernateException {
108         if ( x == y ) return true;
109         if ( x == null || y == null ) return false;
110         Object JavaDoc[] xvalues = getPropertyValues(x, entityMode);
111         Object JavaDoc[] yvalues = getPropertyValues(y, entityMode);
112         for ( int i = 0; i < propertySpan; i++ ) {
113             if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode ) ) return false;
114         }
115         return true;
116     }
117
118     public boolean isEqual(Object JavaDoc x, Object JavaDoc y, EntityMode entityMode, SessionFactoryImplementor factory)
119     throws HibernateException {
120         if ( x == y ) return true;
121         if ( x == null || y == null ) return false;
122         Object JavaDoc[] xvalues = getPropertyValues(x, entityMode);
123         Object JavaDoc[] yvalues = getPropertyValues(y, entityMode);
124         for ( int i = 0; i < propertySpan; i++ ) {
125             if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode, factory ) ) return false;
126         }
127         return true;
128     }
129
130     public int compare(Object JavaDoc x, Object JavaDoc y, EntityMode entityMode) {
131         if ( x == y ) return 0;
132         Object JavaDoc[] xvalues = getPropertyValues(x, entityMode);
133         Object JavaDoc[] yvalues = getPropertyValues(y, entityMode);
134         for ( int i = 0; i < propertySpan; i++ ) {
135             int propertyCompare = propertyTypes[i].compare( xvalues[i], yvalues[i], entityMode );
136             if ( propertyCompare != 0 ) return propertyCompare;
137         }
138         return 0;
139     }
140     
141     public boolean isMethodOf(Method JavaDoc method) {
142         return false;
143     }
144
145     public int getHashCode(Object JavaDoc x, EntityMode entityMode) {
146         int result = 17;
147         Object JavaDoc[] values = getPropertyValues(x, entityMode);
148         for ( int i = 0; i < propertySpan; i++ ) {
149             Object JavaDoc y = values[i];
150             result *= 37;
151             if ( y != null ) result += propertyTypes[i].getHashCode( y, entityMode );
152         }
153         return result;
154     }
155
156     public int getHashCode(Object JavaDoc x, EntityMode entityMode, SessionFactoryImplementor factory) {
157         int result = 17;
158         Object JavaDoc[] values = getPropertyValues(x, entityMode);
159         for ( int i = 0; i < propertySpan; i++ ) {
160             Object JavaDoc y = values[i];
161             result *= 37;
162             if ( y != null ) result += propertyTypes[i].getHashCode( y, entityMode, factory );
163         }
164         return result;
165     }
166
167     public boolean isDirty(Object JavaDoc x, Object JavaDoc y, SessionImplementor session)
168     throws HibernateException {
169         if ( x == y ) return false;
170         if ( x == null || y == null ) return true;
171         EntityMode entityMode = session.getEntityMode();
172         Object JavaDoc[] xvalues = getPropertyValues(x, entityMode);
173         Object JavaDoc[] yvalues = getPropertyValues(y, entityMode);
174         for ( int i = 0; i < xvalues.length; i++ ) {
175             if ( propertyTypes[i].isDirty( xvalues[i], yvalues[i], session ) ) return true;
176         }
177         return false;
178     }
179
180     public Object JavaDoc nullSafeGet(ResultSet JavaDoc rs, String JavaDoc[] names, SessionImplementor session, Object JavaDoc owner)
181             throws HibernateException, SQLException JavaDoc {
182         return resolve( hydrate( rs, names, session, owner ), session, owner );
183     }
184
185     public void nullSafeSet(PreparedStatement JavaDoc st, Object JavaDoc value, int begin, SessionImplementor session)
186     throws HibernateException, SQLException JavaDoc {
187
188         Object JavaDoc[] subvalues = nullSafeGetValues( value, session.getEntityMode() );
189
190         for ( int i = 0; i < propertySpan; i++ ) {
191             propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session );
192             begin += propertyTypes[i].getColumnSpan( session.getFactory() );
193         }
194     }
195
196     public void nullSafeSet(
197             PreparedStatement JavaDoc st,
198             Object JavaDoc value,
199             int begin,
200             boolean[] settable,
201             SessionImplementor session)
202     throws HibernateException, SQLException JavaDoc {
203
204         Object JavaDoc[] subvalues = nullSafeGetValues( value, session.getEntityMode() );
205         
206         int loc = 0;
207         for ( int i = 0; i < propertySpan; i++ ) {
208             int len = propertyTypes[i].getColumnSpan( session.getFactory() );
209             if (len==1) {
210                 if ( settable[loc] ) {
211                     propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session );
212                     begin++;
213                 }
214             }
215             else {
216                 boolean[] subsettable = new boolean[len];
217                 System.arraycopy(settable, loc, subsettable, 0, len);
218                 propertyTypes[i].nullSafeSet( st, subvalues[i], begin, subsettable, session );
219                 begin += ArrayHelper.countTrue(subsettable);
220             }
221             loc += len;
222         }
223     }
224
225     private Object JavaDoc[] nullSafeGetValues(Object JavaDoc value, EntityMode entityMode) throws HibernateException {
226         if ( value == null ) {
227             return new Object JavaDoc[propertySpan];
228         }
229         else {
230             return getPropertyValues( value, entityMode );
231         }
232     }
233
234     public Object JavaDoc nullSafeGet(ResultSet JavaDoc rs, String JavaDoc name, SessionImplementor session, Object JavaDoc owner)
235             throws HibernateException, SQLException JavaDoc {
236
237         return nullSafeGet( rs, new String JavaDoc[]{name}, session, owner );
238     }
239
240     public Object JavaDoc getPropertyValue(Object JavaDoc component, int i, SessionImplementor session)
241             throws HibernateException {
242         return getPropertyValue( component, i, session.getEntityMode() );
243     }
244
245     public Object JavaDoc getPropertyValue(Object JavaDoc component, int i, EntityMode entityMode)
246     throws HibernateException {
247         return tuplizers.getTuplizer(entityMode).getPropertyValue( component, i );
248     }
249
250     public Object JavaDoc[] getPropertyValues(Object JavaDoc component, SessionImplementor session)
251             throws HibernateException {
252         return getPropertyValues( component, session.getEntityMode() );
253     }
254
255     public Object JavaDoc[] getPropertyValues(Object JavaDoc component, EntityMode entityMode)
256     throws HibernateException {
257         return tuplizers.getTuplizer(entityMode).getPropertyValues(component);
258     }
259
260     public void setPropertyValues(Object JavaDoc component, Object JavaDoc[] values, EntityMode entityMode)
261     throws HibernateException {
262         tuplizers.getTuplizer(entityMode).setPropertyValues(component, values);
263     }
264
265     public Type[] getSubtypes() {
266         return propertyTypes;
267     }
268
269     public String JavaDoc getName() {
270         return "component" + ArrayHelper.toString(propertyNames);
271     }
272
273     public String JavaDoc toLoggableString(Object JavaDoc value, SessionFactoryImplementor factory)
274             throws HibernateException {
275         if ( value == null ) return "null";
276         Map JavaDoc result = new HashMap JavaDoc();
277         EntityMode entityMode = tuplizers.guessEntityMode(value);
278         if (entityMode==null) {
279             throw new ClassCastException JavaDoc( value.getClass().getName() );
280         }
281         Object JavaDoc[] values = getPropertyValues( value, entityMode );
282         for ( int i = 0; i < propertyTypes.length; i++ ) {
283             result.put( propertyNames[i], propertyTypes[i].toLoggableString( values[i], factory ) );
284         }
285         return StringHelper.unqualify( getName() ) + result.toString();
286     }
287
288     public String JavaDoc[] getPropertyNames() {
289         return propertyNames;
290     }
291
292     public Object JavaDoc deepCopy(Object JavaDoc component, EntityMode entityMode, SessionFactoryImplementor factory)
293     throws HibernateException {
294         if ( component == null ) return null;
295
296         Object JavaDoc[] values = getPropertyValues( component, entityMode );
297         for ( int i = 0; i < propertySpan; i++ ) {
298             values[i] = propertyTypes[i].deepCopy( values[i], entityMode, factory );
299         }
300
301         Object JavaDoc result = instantiate(entityMode);
302         setPropertyValues( result, values, entityMode );
303
304         //not absolutely necessary, but helps for some
305
//equals()/hashCode() implementations
306
ComponentTuplizer ct = (ComponentTuplizer) tuplizers.getTuplizer(entityMode);
307         if ( ct.hasParentProperty() ) {
308             ct.setParent( result, ct.getParent(component), factory );
309         }
310
311         return result;
312     }
313
314     public Object JavaDoc replace(
315             Object JavaDoc original,
316             Object JavaDoc target,
317             SessionImplementor session,
318             Object JavaDoc owner,
319             Map JavaDoc copyCache)
320         throws HibernateException {
321
322         if ( original == null ) return null;
323         //if ( original == target ) return target;
324

325         final Object JavaDoc result = target == null ?
326                 instantiate( owner, session ) :
327                 target;
328                 
329         final EntityMode entityMode = session.getEntityMode();
330         Object JavaDoc[] values = TypeFactory.replace(
331                 getPropertyValues( original, entityMode ),
332                 getPropertyValues( result, entityMode ),
333                 propertyTypes,
334                 session,
335                 owner,
336                 copyCache
337             );
338
339         setPropertyValues( result, values, entityMode );
340         return result;
341     }
342
343     public Object JavaDoc replace(
344             Object JavaDoc original,
345             Object JavaDoc target,
346             SessionImplementor session,
347             Object JavaDoc owner,
348             Map JavaDoc copyCache,
349             ForeignKeyDirection foreignKeyDirection)
350         throws HibernateException {
351
352         if ( original == null ) return null;
353         //if ( original == target ) return target;
354

355         final Object JavaDoc result = target == null ?
356                 instantiate( owner, session ) :
357                 target;
358                 
359         final EntityMode entityMode = session.getEntityMode();
360         Object JavaDoc[] values = TypeFactory.replace(
361                 getPropertyValues( original, entityMode ),
362                 getPropertyValues( result, entityMode ),
363                 propertyTypes,
364                 session,
365                 owner,
366                 copyCache,
367                 foreignKeyDirection
368             );
369
370         setPropertyValues( result, values, entityMode );
371         return result;
372     }
373
374     /**
375      * This method does not populate the component parent
376      */

377     public Object JavaDoc instantiate(EntityMode entityMode) throws HibernateException {
378         return tuplizers.getTuplizer(entityMode).instantiate();
379     }
380
381     public Object JavaDoc instantiate(Object JavaDoc parent, SessionImplementor session)
382     throws HibernateException {
383         
384         Object JavaDoc result = instantiate( session.getEntityMode() );
385
386         ComponentTuplizer ct = (ComponentTuplizer) tuplizers.getTuplizer( session.getEntityMode() );
387         if ( ct.hasParentProperty() && parent != null ) {
388             ct.setParent(
389                     result,
390                     session.getPersistenceContext().proxyFor( parent ),
391                     session.getFactory()
392                 );
393         }
394         
395         return result;
396     }
397
398     public CascadeStyle getCascadeStyle(int i) {
399         return cascade[i];
400     }
401
402     public boolean isMutable() {
403         return true;
404     }
405
406     public Serializable JavaDoc disassemble(Object JavaDoc value, SessionImplementor session, Object JavaDoc owner)
407             throws HibernateException {
408
409         if ( value == null ) {
410             return null;
411         }
412         else {
413             Object JavaDoc[] values = getPropertyValues( value, session.getEntityMode() );
414             for ( int i = 0; i < propertyTypes.length; i++ ) {
415                 values[i] = propertyTypes[i].disassemble( values[i], session, owner );
416             }
417             return values;
418         }
419     }
420
421     public Object JavaDoc assemble(Serializable JavaDoc object, SessionImplementor session, Object JavaDoc owner)
422             throws HibernateException {
423
424         if ( object == null ) {
425             return null;
426         }
427         else {
428             Object JavaDoc[] values = (Object JavaDoc[]) object;
429             Object JavaDoc[] assembled = new Object JavaDoc[values.length];
430             for ( int i = 0; i < propertyTypes.length; i++ ) {
431                 assembled[i] = propertyTypes[i].assemble( ( Serializable JavaDoc ) values[i], session, owner );
432             }
433             Object JavaDoc result = instantiate( owner, session );
434             setPropertyValues( result, assembled, session.getEntityMode() );
435             return result;
436         }
437     }
438
439     public FetchMode getFetchMode(int i) {
440         return joinedFetch[i];
441     }
442
443     public Object JavaDoc hydrate(
444             final ResultSet JavaDoc rs,
445             final String JavaDoc[] names,
446             final SessionImplementor session,
447             final Object JavaDoc owner)
448     throws HibernateException, SQLException JavaDoc {
449
450         int begin = 0;
451         boolean notNull = false;
452         Object JavaDoc[] values = new Object JavaDoc[propertySpan];
453         for ( int i = 0; i < propertySpan; i++ ) {
454             int length = propertyTypes[i].getColumnSpan( session.getFactory() );
455             String JavaDoc[] range = ArrayHelper.slice( names, begin, length ); //cache this
456
Object JavaDoc val = propertyTypes[i].hydrate( rs, range, session, owner );
457             if ( val == null ) {
458                 if (isKey) return null; //different nullability rules for pk/fk
459
}
460             else {
461                 notNull = true;
462             }
463             values[i] = val;
464             begin += length;
465         }
466
467         return notNull ? values : null;
468     }
469
470     public Object JavaDoc resolve(Object JavaDoc value, SessionImplementor session, Object JavaDoc owner)
471         throws HibernateException {
472
473         if ( value != null ) {
474             Object JavaDoc result = instantiate( owner, session );
475             Object JavaDoc[] values = ( Object JavaDoc[] ) value;
476             Object JavaDoc[] resolvedValues = new Object JavaDoc[values.length]; //only really need new array during semiresolve!
477
for ( int i = 0; i < values.length; i++ ) {
478                 resolvedValues[i] = propertyTypes[i].resolve( values[i], session, owner );
479             }
480             setPropertyValues( result, resolvedValues, session.getEntityMode() );
481             return result;
482         }
483         else {
484             return null;
485         }
486     }
487
488     public Object JavaDoc semiResolve(Object JavaDoc value, SessionImplementor session, Object JavaDoc owner)
489             throws HibernateException {
490         //note that this implementation is kinda broken
491
//for components with many-to-one associations
492
return resolve( value, session, owner );
493     }
494
495     public boolean isModified(Object JavaDoc old, Object JavaDoc current, SessionImplementor session)
496             throws HibernateException {
497
498         if ( current == null ) return old != null;
499         if ( old == null ) return current != null;
500         Object JavaDoc[] currentValues = getPropertyValues( current, session );
501         Object JavaDoc[] oldValues = ( Object JavaDoc[] ) old;
502         for ( int i = 0; i < currentValues.length; i++ ) {
503             if ( propertyTypes[i].isModified( oldValues[i], currentValues[i], session ) ) {
504                 return true;
505             }
506         }
507         return false;
508
509     }
510
511     public boolean[] getPropertyNullability() {
512         return propertyNullability;
513     }
514
515     public boolean isXMLElement() {
516         return true;
517     }
518
519     public Object JavaDoc fromXMLNode(Node xml, Mapping factory) throws HibernateException {
520         return xml;
521     }
522
523     public void setToXMLNode(Node node, Object JavaDoc value, SessionFactoryImplementor factory) throws HibernateException {
524         replaceNode( node, (Element) value );
525     }
526
527     public boolean[] toColumnNullness(Object JavaDoc value, Mapping mapping) {
528         boolean[] result = new boolean[ getColumnSpan(mapping) ];
529         if (value==null) return result;
530         Object JavaDoc[] values = getPropertyValues(value, EntityMode.POJO); //TODO!!!!!!!
531
int loc = 0;
532         for ( int i=0; i<propertyTypes.length; i++ ) {
533             boolean[] propertyNullness = propertyTypes[i].toColumnNullness( values[i], mapping );
534             System.arraycopy(propertyNullness, 0, result, loc, propertyNullness.length);
535             loc += propertyNullness.length;
536         }
537         return result;
538     }
539
540 }
541
Popular Tags