1 21 package oracle.toplink.essentials.internal.indirection; 23 24 import java.util.*; 25 import oracle.toplink.essentials.mappings.*; 26 import oracle.toplink.essentials.queryframework.*; 27 import oracle.toplink.essentials.indirection.*; 28 import oracle.toplink.essentials.exceptions.*; 29 import oracle.toplink.essentials.internal.descriptors.*; 30 import oracle.toplink.essentials.internal.queryframework.*; 31 import oracle.toplink.essentials.internal.helper.*; 32 import oracle.toplink.essentials.internal.sessions.AbstractRecord; 33 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl; 34 import oracle.toplink.essentials.internal.sessions.AbstractSession; 35 36 48 public class TransparentIndirectionPolicy extends IndirectionPolicy { 49 protected static Integer defaultContainerSize; 51 52 56 public TransparentIndirectionPolicy() { 57 super(); 58 } 59 60 64 public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) { 65 if ((!(attributeValue instanceof IndirectContainer)) || objectIsInstantiated(attributeValue)) { 67 return super.backupCloneAttribute(attributeValue, clone, backup, unitOfWork); 68 } else { 69 return buildBackupClone((IndirectContainer)attributeValue); 70 } 71 } 72 73 82 protected Object buildBackupClone(IndirectContainer container) { 83 UnitOfWorkValueHolder containerValueHolder = (UnitOfWorkValueHolder)container.getValueHolder(); 84 BackupValueHolder backupValueHolder = new BackupValueHolder(containerValueHolder); 86 containerValueHolder.setBackupValueHolder(backupValueHolder); 87 return this.buildIndirectContainer(backupValueHolder); 88 } 89 90 94 protected IndirectContainer buildIndirectContainer() { 95 if (defaultContainerSize != null) { 97 return (IndirectContainer)getContainerPolicy().containerInstance(getDefaultContainerSize()); 98 } else { 99 return (IndirectContainer)getContainerPolicy().containerInstance(); 100 } 101 } 102 103 106 protected Object buildIndirectContainer(ValueHolderInterface valueHolder) { 107 IndirectContainer result = buildIndirectContainer(); 108 result.setValueHolder(valueHolder); 109 return result; 110 } 111 112 118 public Object cloneAttribute(Object attributeValue, Object original, Object clone, UnitOfWorkImpl unitOfWork, boolean buildDirectlyFromRow) { 119 ValueHolderInterface valueHolder = null; 120 Object container = null; 121 if (attributeValue instanceof IndirectContainer) { 122 valueHolder = ((IndirectContainer)attributeValue).getValueHolder(); 123 } 124 if (!buildDirectlyFromRow && unitOfWork.isOriginalNewObject(original)) { 125 if ((valueHolder instanceof DatabaseValueHolder) 128 && (! ((DatabaseValueHolder) valueHolder).isInstantiated()) 129 && (((DatabaseValueHolder) valueHolder).getSession() == null) 130 && (! ((DatabaseValueHolder) valueHolder).isSerializedRemoteUnitOfWorkValueHolder())) { 131 throw DescriptorException.attemptToRegisterDeadIndirection(original, getMapping()); 132 } 133 if (getMapping().getRelationshipPartner() == null) { 134 container = getMapping().buildCloneForPartObject(attributeValue, original, clone, unitOfWork, false); 135 } else { 136 if (!(attributeValue instanceof IndirectContainer)) { 137 valueHolder = new ValueHolder(attributeValue); 138 } 139 AbstractRecord row = null; 140 if (valueHolder instanceof DatabaseValueHolder) { 141 row = ((DatabaseValueHolder)valueHolder).getRow(); 142 } 143 144 UnitOfWorkValueHolder newValueHolder = this.getMapping().createUnitOfWorkValueHolder(valueHolder, original, clone, row, unitOfWork, buildDirectlyFromRow); 150 container = buildIndirectContainer(newValueHolder); 151 Object cloneCollection = getMapping().buildCloneForPartObject(attributeValue, original, clone, unitOfWork, false); 152 newValueHolder.privilegedSetValue(cloneCollection); 153 newValueHolder.setInstantiated(); 154 } 155 } else { 156 if (!(attributeValue instanceof IndirectContainer)) { 157 valueHolder = new ValueHolder(attributeValue); 158 } 159 AbstractRecord row = null; 160 if (valueHolder instanceof DatabaseValueHolder) { 161 row = ((DatabaseValueHolder)valueHolder).getRow(); 162 } 163 container = buildIndirectContainer(getMapping().createUnitOfWorkValueHolder(valueHolder, original, clone, row, unitOfWork, buildDirectlyFromRow)); 164 } 165 return container; 166 } 167 168 174 protected boolean containerPolicyIsValid() { 175 if (Helper.classImplementsInterface(this.getContainerClass(), ClassConstants.IndirectContainer_Class)) { 176 return true; 177 } 178 return false; 179 } 180 181 188 public Vector extractPrimaryKeyForReferenceObject(Object referenceObject, AbstractSession session) { 189 throw DescriptorException.invalidUseOfTransparentIndirection(this.getMapping()); 190 } 191 192 199 public AbstractRecord extractReferenceRow(Object referenceObject) { 200 if (this.objectIsInstantiated(referenceObject)) { 201 return null; 202 } else { 203 return ((DatabaseValueHolder)((IndirectContainer)referenceObject).getValueHolder()).getRow(); 204 } 205 } 206 207 211 protected Class getContainerClass() { 212 return this.getContainerPolicy().getContainerClass(); 213 } 214 215 219 protected ContainerPolicy getContainerPolicy() { 220 return this.getCollectionMapping().getContainerPolicy(); 221 } 222 223 227 protected static int getDefaultContainerSize() { 228 return defaultContainerSize.intValue(); 230 } 231 232 236 public Object getOriginalIndirectionObject(Object unitOfWorkIndirectionObject, AbstractSession session) { 237 IndirectContainer container = (IndirectContainer)unitOfWorkIndirectionObject; 238 if (container.getValueHolder() instanceof UnitOfWorkValueHolder) { 239 ValueHolderInterface valueHolder = ((UnitOfWorkValueHolder)container.getValueHolder()).getWrappedValueHolder(); 240 return buildIndirectContainer(valueHolder); 241 } else { 242 return container; 243 } 244 } 245 246 251 public Object getRealAttributeValueFromObject(Object object) { 252 this.getContainerPolicy().sizeFor(object); return object; 254 } 255 256 262 public void setRealAttributeValueInObject(Object target, Object attributeValue) { 263 264 278 super.setRealAttributeValueInObject(target, attributeValue); 279 } 280 281 285 public void iterateOnAttributeValue(DescriptorIterator iterator, Object attributeValue) { 286 if (attributeValue instanceof IndirectContainer) { 287 iterator.iterateIndirectContainerForMapping((IndirectContainer)attributeValue, this.getMapping()); 288 } else { super.iterateOnAttributeValue(iterator, attributeValue); 290 } 291 } 292 293 300 public Object nullValueFromRow() { 301 throw DescriptorException.invalidUseOfTransparentIndirection(this.getMapping()); 302 } 303 304 308 public boolean objectIsInstantiated(Object object) { 309 if (object instanceof IndirectContainer) { 310 return ((IndirectContainer)object).isInstantiated(); 311 } else { 312 return true; } 314 } 315 316 320 public static void setDefaultContainerSize(int defaultSize) { 321 defaultContainerSize = new Integer (defaultSize); 323 } 324 325 334 protected boolean typeIsValid(Class declaredType) { 335 if (Helper.classIsSubclass(this.getContainerClass(), declaredType)) { 336 return true; 337 } 338 if (Helper.classImplementsInterface(this.getContainerClass(), declaredType)) { 339 return true; 340 } 341 return false; 342 } 343 344 348 public boolean usesTransparentIndirection(){ 349 return true; 350 } 351 352 360 public Object validateAttributeOfInstantiatedObject(Object attributeValue) { 361 if (attributeValue == null) { 365 return buildIndirectContainer(); 366 } 367 if (!(this.getContainerPolicy().isValidContainer(attributeValue))) { 368 throw DescriptorException.indirectContainerInstantiationMismatch(attributeValue, this.getMapping()); 369 } 370 return attributeValue; 371 } 372 373 379 public void validateContainerPolicy(IntegrityChecker checker) throws DescriptorException { 380 super.validateContainerPolicy(checker); 381 if (!this.containerPolicyIsValid()) { 382 checker.handleError(DescriptorException.invalidContainerPolicyWithTransparentIndirection(this.getMapping(), this.getContainerPolicy())); 383 } 384 385 if (getContainerPolicy().isMapPolicy() && ((((ForeignReferenceMapping)getMapping()).getRelationshipPartnerAttributeName() != null) || (getMapping().getRelationshipPartner() != null))) { 387 checker.handleError(DescriptorException.unsupportedTypeForBidirectionalRelationshipMaintenance(this.getMapping(), this.getContainerPolicy())); 388 } 389 } 390 391 399 public void validateDeclaredAttributeType(Class attributeType, IntegrityChecker checker) throws DescriptorException { 400 super.validateDeclaredAttributeType(attributeType, checker); 401 if (!this.typeIsValid(attributeType)) { 402 checker.handleError(DescriptorException.attributeAndMappingWithTransparentIndirectionMismatch(this.getMapping(), this.validTypeName())); 403 } 404 } 405 406 414 public void validateGetMethodReturnType(Class returnType, IntegrityChecker checker) throws DescriptorException { 415 super.validateGetMethodReturnType(returnType, checker); 416 if (!this.typeIsValid(returnType)) { 417 checker.handleError(DescriptorException.returnAndMappingWithTransparentIndirectionMismatch(this.getMapping(), this.validTypeName())); 418 } 419 } 420 421 429 public void validateSetMethodParameterType(Class parameterType, IntegrityChecker checker) throws DescriptorException { 430 super.validateSetMethodParameterType(parameterType, checker); 431 if (!this.typeIsValid(parameterType)) { 432 checker.handleError(DescriptorException.parameterAndMappingWithTransparentIndirectionMismatch(this.getMapping(), this.validTypeName())); 433 } 434 } 435 436 440 protected String validTypeName() { 441 return Helper.getShortClassName(this.getContainerClass()); 442 } 443 444 451 public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) { 452 throw DescriptorException.invalidUseOfTransparentIndirection(this.getMapping()); 453 } 454 455 461 public Object valueFromQuery(ReadQuery query, AbstractRecord row, AbstractSession session) { 462 return this.buildIndirectContainer(new QueryBasedValueHolder(query, row, session)); 463 } 464 465 471 public Object valueFromQuery(ReadQuery query, AbstractRecord row, Object object, AbstractSession session) { 472 return valueFromQuery(query, row, session); 473 } 474 475 480 public Object valueFromRow(Object object) { 481 return object; 482 } 483 } 484 | Popular Tags |