1 package org.hibernate.type; 3 4 import java.io.Serializable ; 5 import java.lang.reflect.Method ; 6 import java.sql.PreparedStatement ; 7 import java.sql.ResultSet ; 8 import java.sql.SQLException ; 9 import java.util.Arrays ; 10 import java.util.Map ; 11 12 import org.dom4j.Node; 13 import org.hibernate.EntityMode; 14 import org.hibernate.FetchMode; 15 import org.hibernate.Hibernate; 16 import org.hibernate.HibernateException; 17 import org.hibernate.MappingException; 18 import org.hibernate.TransientObjectException; 19 import org.hibernate.engine.CascadeStyle; 20 import org.hibernate.engine.ForeignKeys; 21 import org.hibernate.engine.Mapping; 22 import org.hibernate.engine.SessionFactoryImplementor; 23 import org.hibernate.engine.SessionImplementor; 24 import org.hibernate.persister.entity.Joinable; 25 import org.hibernate.proxy.HibernateProxyHelper; 26 import org.hibernate.util.ArrayHelper; 27 28 32 public class AnyType extends AbstractType implements AbstractComponentType, AssociationType { 33 34 private final Type identifierType; 35 private final Type metaType; 36 37 public AnyType(Type metaType, Type identifierType) { 38 this.identifierType = identifierType; 39 this.metaType = metaType; 40 } 41 42 public AnyType() { 43 this(Hibernate.STRING, Hibernate.SERIALIZABLE); 44 } 45 46 public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 47 throws HibernateException { 48 return value; 49 } 50 51 public boolean isMethodOf(Method method) { 52 return false; 53 } 54 55 public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException { 56 return x==y; 57 } 58 59 public int compare(Object x, Object y, EntityMode entityMode) { 60 return 0; } 62 63 public int getColumnSpan(Mapping session) 64 throws MappingException { 65 return 2; 66 } 67 68 public String getName() { 69 return "object"; 70 } 71 72 public boolean isMutable() { 73 return false; 74 } 75 76 public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) 77 throws HibernateException, SQLException { 78 79 throw new UnsupportedOperationException ("object is a multicolumn type"); 80 } 81 82 public Object nullSafeGet(ResultSet rs, String [] names, SessionImplementor session, Object owner) 83 throws HibernateException, SQLException { 84 return resolveAny( 85 (String ) metaType.nullSafeGet(rs, names[0], session, owner), 86 (Serializable ) identifierType.nullSafeGet(rs, names[1], session, owner), 87 session 88 ); 89 } 90 91 public Object hydrate(ResultSet rs, String [] names, SessionImplementor session, Object owner) 92 throws HibernateException, SQLException { 93 String entityName = (String ) metaType.nullSafeGet(rs, names[0], session, owner); 94 Serializable id = (Serializable ) identifierType.nullSafeGet(rs, names[1], session, owner); 95 return new ObjectTypeCacheEntry(entityName, id); 96 } 97 98 public Object resolve(Object value, SessionImplementor session, Object owner) 99 throws HibernateException { 100 ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) value; 101 return resolveAny(holder.entityName, holder.id, session); 102 } 103 104 public Object semiResolve(Object value, SessionImplementor session, Object owner) 105 throws HibernateException { 106 throw new UnsupportedOperationException ("any mappings may not form part of a property-ref"); 107 } 108 109 private Object resolveAny(String entityName, Serializable id, SessionImplementor session) 110 throws HibernateException { 111 return entityName==null || id==null ? 112 null : session.internalLoad( entityName, id, false, false ); 113 } 114 115 public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) 116 throws HibernateException, SQLException { 117 nullSafeSet(st, value, index, null, session); 118 } 119 120 public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) 121 throws HibernateException, SQLException { 122 123 Serializable id; 124 String entityName; 125 if (value==null) { 126 id=null; 127 entityName=null; 128 } 129 else { 130 entityName = session.bestGuessEntityName(value); 131 id = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, value, session); 132 } 133 134 if ( settable==null || settable[0] ) { 136 metaType.nullSafeSet(st, entityName, index, session); 137 } 138 if (settable==null) { 139 identifierType.nullSafeSet(st, id, index+1, session); 140 } 141 else { 142 boolean[] idsettable = new boolean[ settable.length-1 ]; 143 System.arraycopy(settable, 1, idsettable, 0, idsettable.length); 144 identifierType.nullSafeSet(st, id, index+1, idsettable, session); 145 } 146 } 147 148 public Class getReturnedClass() { 149 return Object .class; 150 } 151 152 public int[] sqlTypes(Mapping mapping) throws MappingException { 153 return ArrayHelper.join( 154 metaType.sqlTypes(mapping), 155 identifierType.sqlTypes(mapping) 156 ); 157 } 158 159 public void setToXMLNode(Node xml, Object value, SessionFactoryImplementor factory) { 160 throw new UnsupportedOperationException ("any types cannot be stringified"); 161 } 162 163 public String toLoggableString(Object value, SessionFactoryImplementor factory) 164 throws HibernateException { 165 return value==null ? 167 "null" : 168 Hibernate.entity( HibernateProxyHelper.getClassWithoutInitializingProxy(value) ) 169 .toLoggableString(value, factory); 170 } 171 172 public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException { 173 throw new UnsupportedOperationException (); } 175 176 public static final class ObjectTypeCacheEntry implements Serializable { 177 String entityName; 178 Serializable id; 179 ObjectTypeCacheEntry(String entityName, Serializable id) { 180 this.entityName = entityName; 181 this.id = id; 182 } 183 } 184 185 public Object assemble( 186 Serializable cached, 187 SessionImplementor session, 188 Object owner) 189 throws HibernateException { 190 191 ObjectTypeCacheEntry e = (ObjectTypeCacheEntry) cached; 192 return e==null ? null : session.internalLoad(e.entityName, e.id, false, false); 193 } 194 195 public Serializable disassemble(Object value, SessionImplementor session, Object owner) 196 throws HibernateException { 197 return value==null ? 198 null : 199 new ObjectTypeCacheEntry( 200 session.bestGuessEntityName(value), 201 ForeignKeys.getEntityIdentifierIfNotUnsaved( 202 session.bestGuessEntityName(value), value, session 203 ) 204 ); 205 } 206 207 public boolean isAnyType() { 208 return true; 209 } 210 211 public Object replace( 212 Object original, 213 Object target, 214 SessionImplementor session, 215 Object owner, 216 Map copyCache) 217 throws HibernateException { 218 if (original==null) { 219 return null; 220 } 221 else { 222 String entityName = session.bestGuessEntityName(original); 223 Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved( 224 entityName, 225 original, 226 session 227 ); 228 return session.internalLoad( 229 entityName, 230 id, 231 false, 232 false 233 ); 234 } 235 } 236 public CascadeStyle getCascadeStyle(int i) { 237 return CascadeStyle.NONE; 238 } 239 240 public FetchMode getFetchMode(int i) { 241 return FetchMode.SELECT; 242 } 243 244 private static final String [] PROPERTY_NAMES = new String [] { "class", "id" }; 245 246 public String [] getPropertyNames() { 247 return PROPERTY_NAMES; 248 } 249 250 public Object getPropertyValue(Object component, int i, SessionImplementor session) 251 throws HibernateException { 252 253 return i==0 ? 254 session.bestGuessEntityName(component) : 255 getIdentifier(component, session); 256 } 257 258 public Object [] getPropertyValues(Object component, SessionImplementor session) 259 throws HibernateException { 260 261 return new Object [] { session.bestGuessEntityName(component), getIdentifier(component, session) }; 262 } 263 264 private Serializable getIdentifier(Object value, SessionImplementor session) throws HibernateException { 265 try { 266 return ForeignKeys.getEntityIdentifierIfNotUnsaved( session.bestGuessEntityName(value), value, session ); 267 } 268 catch (TransientObjectException toe) { 269 return null; 270 } 271 } 272 273 public Type[] getSubtypes() { 274 return new Type[] { metaType, identifierType }; 275 } 276 277 public void setPropertyValues(Object component, Object [] values, EntityMode entityMode) 278 throws HibernateException { 279 280 throw new UnsupportedOperationException (); 281 282 } 283 284 public Object [] getPropertyValues(Object component, EntityMode entityMode) { 285 throw new UnsupportedOperationException (); 286 } 287 288 public boolean isComponentType() { 289 return true; 290 } 291 292 public ForeignKeyDirection getForeignKeyDirection() { 293 return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT; 295 } 296 297 public boolean isAssociationType() { 298 return true; 299 } 300 301 public boolean useLHSPrimaryKey() { 302 return false; 303 } 304 305 public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) { 306 throw new UnsupportedOperationException ("any types do not have a unique referenced persister"); 307 } 308 309 public boolean isModified(Object old, Object current, SessionImplementor session) 310 throws HibernateException { 311 if (current==null) return old!=null; 312 if (old==null) return current!=null; 313 ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) old; 314 return !holder.entityName.equals( session.bestGuessEntityName(current) ) || 315 identifierType.isModified(holder.id, getIdentifier(current, session), session); 316 } 317 318 public String getAssociatedEntityName(SessionFactoryImplementor factory) 319 throws MappingException { 320 throw new UnsupportedOperationException ("any types do not have a unique referenced persister"); 321 } 322 323 public boolean[] getPropertyNullability() { 324 return null; 325 } 326 327 public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) 328 throws MappingException { 329 throw new UnsupportedOperationException (); 330 } 331 332 public boolean isReferenceToPrimaryKey() { 333 return true; 334 } 335 336 public String getRHSUniqueKeyPropertyName() { 337 return null; 338 } 339 340 public String getLHSPropertyName() { 341 return null; 342 } 343 344 public boolean isAlwaysDirtyChecked() { 345 return false; 346 } 347 348 public boolean isEmbeddedInXML() { 349 return false; 350 } 351 352 public boolean[] toColumnNullness(Object value, Mapping mapping) { 353 boolean[] result = new boolean[ getColumnSpan(mapping) ]; 354 if (value!=null) Arrays.fill(result, true); 355 return result; 356 } 357 } 358 | Popular Tags |