0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * // Copyright (c) 1998, 2007, Oracle. All rights reserved.
0005: *
0006: *
0007: * The contents of this file are subject to the terms of either the GNU
0008: * General Public License Version 2 only ("GPL") or the Common Development
0009: * and Distribution License("CDDL") (collectively, the "License"). You
0010: * may not use this file except in compliance with the License. You can obtain
0011: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
0012: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
0013: * language governing permissions and limitations under the License.
0014: *
0015: * When distributing the software, include this License Header Notice in each
0016: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
0017: * Sun designates this particular file as subject to the "Classpath" exception
0018: * as provided by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the License
0020: * Header, with the fields enclosed by brackets [] replaced by your own
0021: * identifying information: "Portions Copyrighted [year]
0022: * [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * If you wish your version of this file to be governed by only the CDDL or
0027: * only the GPL Version 2, indicate your decision by adding "[Contributor]
0028: * elects to include this software in this distribution under the [CDDL or GPL
0029: * Version 2] license." If you don't indicate a single choice of license, a
0030: * recipient has the option to distribute your version of this file under
0031: * either the CDDL, the GPL Version 2 or to extend the choice of license to
0032: * its licensees as provided above. However, if you add GPL Version 2 code
0033: * and therefore, elected the GPL Version 2 license, then the option applies
0034: * only if the new code is made subject to such option by the copyright
0035: * holder.
0036: */
0037: package oracle.toplink.essentials.mappings;
0038:
0039: import java.io.*;
0040: import java.util.*;
0041: import oracle.toplink.essentials.descriptors.ClassDescriptor;
0042: import oracle.toplink.essentials.exceptions.*;
0043: import oracle.toplink.essentials.expressions.*;
0044: import oracle.toplink.essentials.indirection.*;
0045: import oracle.toplink.essentials.internal.descriptors.*;
0046: import oracle.toplink.essentials.internal.expressions.*;
0047: import oracle.toplink.essentials.internal.helper.*;
0048: import oracle.toplink.essentials.internal.indirection.*;
0049: import oracle.toplink.essentials.internal.queryframework.*;
0050: import oracle.toplink.essentials.internal.sessions.*;
0051: import oracle.toplink.essentials.queryframework.*;
0052: import oracle.toplink.essentials.sessions.ObjectCopyingPolicy;
0053: import oracle.toplink.essentials.internal.sessions.AbstractRecord;
0054: import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
0055: import oracle.toplink.essentials.internal.sessions.AbstractSession;
0056:
0057: /**
0058: * <p><b>Purpose</b>: Defines how an attribute of an object maps to and from the database
0059: *
0060: * <p><b>Responsibilities</b>:<ul>
0061: * <li> Define type of relationship (1:1/1:M/M:M/etc.)
0062: * <li> Define instance variable name and fields names required
0063: * <li> Define any additional properties (ownership, indirection, read only, etc.)
0064: * <li> Control building the value for the instance variable from the database row
0065: * <li> Control building the database fields from the object
0066: * <li> Control any pre/post updating/inserting/deleting required to maintain the relationship
0067: * <li> Merges object changes for unit of work.
0068: * <li> Clones objects for unit of work.
0069: * <li> cache computed information to optimize performance
0070: * </ul>
0071: *
0072: * @author Sati
0073: * @since TOPLink/Java 1.0
0074: */
0075: public abstract class DatabaseMapping implements Cloneable,
0076: Serializable {
0077:
0078: /** Used to reduce memory for mappings with no fields. */
0079: protected static final Vector NO_FIELDS = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
0080: .newInstance(0);
0081:
0082: /** Used to share integer instance to reduce memory. */
0083: protected static final Integer NO_WEIGHT = new Integer(
0084: Integer.MAX_VALUE);
0085: protected static final Integer WEIGHT_1 = new Integer(1);
0086:
0087: /** Descriptor to which this mapping belongs to */
0088: protected ClassDescriptor descriptor;
0089:
0090: /** Wrapper to store the reference objects. */
0091: protected AttributeAccessor attributeAccessor;
0092:
0093: /** Makes this mapping read only. No write are performed on it. Default is false */
0094: protected boolean isReadOnly;
0095:
0096: /** Specifies whether this mapping is optional (i.e. field may be null). Used for DDL generation. */
0097: protected boolean isOptional;
0098:
0099: /** Fields associated with the mappings are cached */
0100: protected Vector<DatabaseField> fields;
0101:
0102: /** It is needed only in remote initialization and mapping is in parent descriptor */
0103: protected boolean isRemotelyInitialized;
0104:
0105: /** This is a TopLink defined attribute that allows us to sort the mappings */
0106: protected Integer weight = NO_WEIGHT;
0107:
0108: /** used as a temporary store for custom SDK usage */
0109: protected Map properties;
0110:
0111: /** used as a quick check to see if this mapping is a primary key mapping,
0112: * set by the object builder during initialization.
0113: */
0114: protected boolean primaryKeyMapping = false;
0115:
0116: /**
0117: * PUBLIC:
0118: * Default constructor.
0119: */
0120: public DatabaseMapping() {
0121: this .isOptional = true;
0122: this .isReadOnly = false;
0123: this .attributeAccessor = new InstanceVariableAttributeAccessor();
0124: }
0125:
0126: /**
0127: * INTERNAL:
0128: * Clone the attribute from the clone and assign it to the backup.
0129: */
0130: public abstract void buildBackupClone(Object clone, Object backup,
0131: UnitOfWorkImpl unitOfWork);
0132:
0133: /**
0134: * INTERNAL:
0135: * Require for cloning, the part must be cloned.
0136: */
0137: public Object buildBackupCloneForPartObject(Object attributeValue,
0138: Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
0139: throw DescriptorException.invalidMappingOperation(this ,
0140: "buildBackupCloneForPartObject");
0141: }
0142:
0143: /**
0144: * INTERNAL:
0145: * Clone the attribute from the original and assign it to the clone.
0146: */
0147: public abstract void buildClone(Object original, Object clone,
0148: UnitOfWorkImpl unitOfWork,
0149: JoinedAttributeManager joinedAttributeManager);
0150:
0151: /**
0152: * INTERNAL:
0153: * A combination of readFromRowIntoObject and buildClone.
0154: * <p>
0155: * buildClone assumes the attribute value exists on the original and can
0156: * simply be copied.
0157: * <p>
0158: * readFromRowIntoObject assumes that one is building an original.
0159: * <p>
0160: * Both of the above assumptions are false in this method, and actually
0161: * attempts to do both at the same time.
0162: * <p>
0163: * Extract value from the row and set the attribute to this value in the
0164: * working copy clone.
0165: * In order to bypass the shared cache when in transaction a UnitOfWork must
0166: * be able to populate working copies directly from the row.
0167: */
0168: public abstract void buildCloneFromRow(AbstractRecord databaseRow,
0169: JoinedAttributeManager joinManager, Object clone,
0170: ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork,
0171: AbstractSession executionSession);
0172:
0173: /**
0174: * INTERNAL:
0175: * Builds a shallow original object. Only direct attributes and primary
0176: * keys are populated. In this way the minimum original required for
0177: * instantiating a working copy clone can be built without placing it in
0178: * the shared cache (no concern over cycles).
0179: */
0180: public void buildShallowOriginalFromRow(AbstractRecord databaseRow,
0181: Object original, ObjectBuildingQuery query,
0182: AbstractSession executionSession) {
0183: return;
0184: }
0185:
0186: /**
0187: * INTERNAL:
0188: * Require for cloning, the part must be cloned.
0189: */
0190: public Object buildCloneForPartObject(Object attributeValue,
0191: Object original, Object clone, UnitOfWorkImpl unitOfWork,
0192: boolean isExisting) {
0193: throw DescriptorException.invalidMappingOperation(this ,
0194: "buildCloneForPartObject");
0195: }
0196:
0197: /**
0198: * INTERNAL:
0199: * Copy of the attribute of the object.
0200: * This is NOT used for unit of work but for templatizing an object.
0201: */
0202: public void buildCopy(Object copy, Object original,
0203: ObjectCopyingPolicy policy) {
0204: }
0205:
0206: /**
0207: * INTERNAL:
0208: * Used to allow object level comparisons.
0209: */
0210: public Expression buildObjectJoinExpression(Expression base,
0211: Object value, AbstractSession session) {
0212: throw QueryException.unsupportedMappingForObjectComparison(
0213: this , base);
0214: }
0215:
0216: /**
0217: * INTERNAL:
0218: * Used to allow object level comparisons.
0219: */
0220: public Expression buildObjectJoinExpression(Expression base,
0221: Expression argument, AbstractSession session) {
0222: throw QueryException.unsupportedMappingForObjectComparison(
0223: this , base);
0224: }
0225:
0226: /**
0227: * INTERNAL:
0228: * Cascade registerNew for Create through mappings that require the cascade
0229: */
0230: abstract public void cascadePerformRemoveIfRequired(Object object,
0231: UnitOfWorkImpl uow, IdentityHashtable visitedObjects);
0232:
0233: /**
0234: * INTERNAL:
0235: * Cascade registerNew for Create through mappings that require the cascade
0236: */
0237: abstract public void cascadeRegisterNewIfRequired(Object object,
0238: UnitOfWorkImpl uow, IdentityHashtable visitedObjects);
0239:
0240: /**
0241: * INTERNAL:
0242: * Used by AttributeLevelChangeTracking to update a changeRecord with calculated changes
0243: * as apposed to detected changes. If an attribute can not be change tracked it's
0244: * changes can be detected through this process.
0245: */
0246: public void calculateDeferredChanges(ChangeRecord changeRecord,
0247: AbstractSession session) {
0248: throw DescriptorException.invalidMappingOperation(this ,
0249: "calculatedDeferredChanges");
0250: }
0251:
0252: /**
0253: * INTERNAL:
0254: * Cascade the merge to the component object, if appropriate.
0255: */
0256: public void cascadeMerge(Object sourceElement,
0257: MergeManager mergeManager) {
0258: throw DescriptorException.invalidMappingOperation(this ,
0259: "cascadeMerge");
0260: }
0261:
0262: /**
0263: * INTERNAL:
0264: * Clones itself.
0265: */
0266: public Object clone() {
0267: // Bug 3037701 - clone the AttributeAccessor
0268: DatabaseMapping mapping = null;
0269: try {
0270: mapping = (DatabaseMapping) super .clone();
0271: } catch (CloneNotSupportedException e) {
0272: throw new InternalError();
0273: }
0274: mapping
0275: .setAttributeAccessor((AttributeAccessor) attributeAccessor
0276: .clone());
0277: return mapping;
0278: }
0279:
0280: /**
0281: * INTERNAL:
0282: * Helper method to clone vector of fields (used in aggregate initialization cloning).
0283: */
0284: protected Vector cloneFields(Vector fields) {
0285: Vector clonedFields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
0286: .newInstance();
0287: for (Enumeration fieldsEnum = fields.elements(); fieldsEnum
0288: .hasMoreElements();) {
0289: clonedFields.addElement(((DatabaseField) fieldsEnum
0290: .nextElement()).clone());
0291: }
0292:
0293: return clonedFields;
0294: }
0295:
0296: /**
0297: * This method must be overwritten in the subclasses to return a vector of all the
0298: * fields this mapping represents.
0299: */
0300: protected Vector<DatabaseField> collectFields() {
0301: return NO_FIELDS;
0302: }
0303:
0304: /**
0305: * INTERNAL:
0306: * This method was created in VisualAge.
0307: * @return prototype.changeset.ChangeRecord
0308: */
0309: abstract public ChangeRecord compareForChange(Object clone,
0310: Object backup, ObjectChangeSet owner,
0311: AbstractSession session);
0312:
0313: /**
0314: * INTERNAL:
0315: * Compare the attributes belonging to this mapping for the objects.
0316: */
0317: public abstract boolean compareObjects(Object firstObject,
0318: Object secondObject, AbstractSession session);
0319:
0320: /**
0321: * INTERNAL:
0322: * Convert all the class-name-based settings in this mapping to actual class-based
0323: * settings
0324: * This method is implemented by subclasses as necessary.
0325: * @param classLoader
0326: */
0327: public void convertClassNamesToClasses(ClassLoader classLoader) {
0328: };
0329:
0330: /**
0331: * INTERNAL:
0332: * Builder the unit of work value holder.
0333: * @param buildDirectlyFromRow indicates that we are building the clone directly
0334: * from a row as opposed to building the original from the row, putting it in
0335: * the shared cache, and then cloning the original.
0336: */
0337: public UnitOfWorkValueHolder createUnitOfWorkValueHolder(
0338: ValueHolderInterface attributeValue, Object original,
0339: Object clone, AbstractRecord row,
0340: UnitOfWorkImpl unitOfWork, boolean buildDirectlyFromRow) {
0341: throw DescriptorException.invalidMappingOperation(this ,
0342: "createUnitOfWorkValueHolder");
0343: }
0344:
0345: /**
0346: * INTERNAL:
0347: * Extract the nested attribute expressions that apply to this mapping.
0348: * This is used for partial objects and joining.
0349: * @param rootExpressionsAllowed true if newRoot itself can be one of the
0350: * expressions returned
0351: */
0352: protected Vector extractNestedExpressions(List expressions,
0353: ExpressionBuilder newRoot, boolean rootExpressionsAllowed) {
0354: Vector nestedExpressions = oracle.toplink.essentials.internal.helper.NonSynchronizedVector
0355: .newInstance(expressions.size());
0356:
0357: for (Iterator expressionsEnum = expressions.iterator(); expressionsEnum
0358: .hasNext();) {
0359: Expression next = (Expression) expressionsEnum.next();
0360:
0361: // The expressionBuilder can be one of the locked expressions in
0362: // the ForUpdateOfClause.
0363: if (!next.isQueryKeyExpression()) {
0364: continue;
0365: }
0366: QueryKeyExpression expression = (QueryKeyExpression) next;
0367: QueryKeyExpression base = expression;
0368: boolean afterBase = false;
0369: while (!base.getBaseExpression().isExpressionBuilder()) {
0370: afterBase = true;
0371: base = (QueryKeyExpression) base.getBaseExpression();
0372: }
0373: if (afterBase && base.getName().equals(getAttributeName())) {
0374: nestedExpressions.addElement(expression.rebuildOn(base,
0375: newRoot));
0376: } else if (rootExpressionsAllowed
0377: && expression.getBaseExpression()
0378: .isExpressionBuilder()
0379: && expression.getName().equals(getAttributeName())) {
0380: nestedExpressions.addElement(newRoot);
0381: }
0382: }
0383: return nestedExpressions;
0384: }
0385:
0386: /**
0387: * ADVANCED:
0388: * Return the attributeAccessor.
0389: * The attribute accessor is responsible for setting and retrieving the attribute value
0390: * from the object for this mapping.
0391: */
0392: public AttributeAccessor getAttributeAccessor() {
0393: return attributeAccessor;
0394: }
0395:
0396: /**
0397: * PUBLIC:
0398: * The classification type for the attribute this mapping represents
0399: */
0400: public Class getAttributeClassification() {
0401: return null;
0402: }
0403:
0404: /**
0405: * PUBLIC:
0406: * Return the name of the attribute set in the mapping.
0407: */
0408: public String getAttributeName() {
0409: return getAttributeAccessor().getAttributeName();
0410: }
0411:
0412: /**
0413: * INTERNAL:
0414: * Return the value of an attribute which this mapping represents for an object.
0415: */
0416: public Object getAttributeValueFromObject(Object object)
0417: throws DescriptorException {
0418: try {
0419: return getAttributeAccessor().getAttributeValueFromObject(
0420: object);
0421: } catch (DescriptorException exception) {
0422: exception.setMapping(this );
0423: throw exception;
0424: }
0425: }
0426:
0427: /**
0428: * INTERNAL:
0429: * Return the mapping's containerPolicy.
0430: */
0431: public ContainerPolicy getContainerPolicy() {
0432: throw DescriptorException.invalidMappingOperation(this ,
0433: "getContainerPolicy");
0434: }
0435:
0436: /**
0437: * INTERNAL:
0438: * Return the descriptor to which this mapping belongs
0439: */
0440: public ClassDescriptor getDescriptor() {
0441: return descriptor;
0442: }
0443:
0444: /**
0445: * INTERNAL:
0446: * Return the field associated with this mapping if there is exactly one.
0447: * This is required for object relational mapping to print them, but because
0448: * they are defined in Enterprise they cannot be cast to.
0449: * Mappings that have a field include direct mappings and object relational mappings.
0450: */
0451: public DatabaseField getField() {
0452: return null;
0453: }
0454:
0455: /**
0456: * INTERNAL:
0457: * Return the classifiction for the field contained in the mapping.
0458: * This is used to convert the row value to a consistent java value.
0459: * By default this is unknown.
0460: */
0461: public Class getFieldClassification(DatabaseField fieldToClassify) {
0462: return null;
0463: }
0464:
0465: /**
0466: * INTERNAL:
0467: * Returns a vector of all the fields this mapping represents.
0468: */
0469: public Vector<DatabaseField> getFields() {
0470: return this .fields;
0471: }
0472:
0473: /**
0474: * PUBLIC:
0475: * This method is invoked reflectively on the reference object to return the value of the
0476: * attribute in the object. This method returns the name of the getMethodName or null if not using method access.
0477: */
0478: public String getGetMethodName() {
0479: if (!(getAttributeAccessor() instanceof MethodAttributeAccessor)) {
0480: return null;
0481: }
0482: return ((MethodAttributeAccessor) getAttributeAccessor())
0483: .getGetMethodName();
0484: }
0485:
0486: /**
0487: * INTERNAL:
0488: * used as a temporary store for custom SDK usage
0489: */
0490: public Map getProperties() {
0491: if (properties == null) {//Lazy initialize to conserve space and allocation time.
0492: properties = new HashMap(5);
0493: }
0494: return properties;
0495: }
0496:
0497: /**
0498: * INTERNAL:
0499: * used as a temporary store for custom SDK usage
0500: */
0501: public Object getProperty(Object property) {
0502: if (properties == null) {
0503: return null;
0504: }
0505:
0506: return getProperties().get(property);
0507: }
0508:
0509: /**
0510: * INTERNAL:
0511: * Return the value of an attribute unwrapping value holders if required.
0512: */
0513: public Object getRealAttributeValueFromObject(Object object,
0514: AbstractSession session) throws DescriptorException {
0515: return getAttributeValueFromObject(object);
0516: }
0517:
0518: /**
0519: * INTERNAL:
0520: * Return the value of an attribute, unwrapping value holders if necessary.
0521: * If the value is null, build a new container.
0522: */
0523: public Object getRealCollectionAttributeValueFromObject(
0524: Object object, AbstractSession session)
0525: throws DescriptorException {
0526: throw DescriptorException.invalidMappingOperation(this ,
0527: "getRealCollectionAttributeValueFromObject");
0528: }
0529:
0530: /**
0531: * INTERNAL:
0532: * Return the referenceDescriptor. This is a descriptor which is associated with
0533: * the reference class.
0534: * Replaced by {@link #getReferenceClassDescriptor()}
0535: */
0536: public ClassDescriptor getReferenceDescriptor() {
0537: return null;
0538: }
0539:
0540: /**
0541: * PUBLIC:
0542: * Return the referenceDescriptor. This is a descriptor which is associated with
0543: * the reference class.
0544: */
0545: public ClassDescriptor getReferenceClassDescriptor() {
0546: ClassDescriptor desc = getReferenceDescriptor();
0547: if (desc instanceof ClassDescriptor) {
0548: return (ClassDescriptor) desc;
0549: } else {
0550: throw ValidationException.cannotCastToClass(desc, desc
0551: .getClass(), ClassDescriptor.class);
0552: }
0553: }
0554:
0555: /**
0556: * INTERNAL:
0557: * Return the relationshipPartner mapping for this bi-directional mapping. If the relationshipPartner is null then
0558: * this is a uni-directional mapping.
0559: */
0560: public DatabaseMapping getRelationshipPartner() {
0561: return null;
0562: }
0563:
0564: /**
0565: * PUBLIC:
0566: * This method is invoked reflectively on the reference object to set the value of the
0567: * attribute in the object. This method returns the name of the setMethodName or null if not using method access.
0568: */
0569: public String getSetMethodName() {
0570: if (!(getAttributeAccessor() instanceof MethodAttributeAccessor)) {
0571: return null;
0572: }
0573: return ((MethodAttributeAccessor) getAttributeAccessor())
0574: .getSetMethodName();
0575: }
0576:
0577: /**
0578: * INTERNAL:
0579: * Return the weight of the mapping, used to sort mappings to ensure that
0580: * DirectToField Mappings get merged first
0581: */
0582: public Integer getWeight() {
0583: return this .weight;
0584: }
0585:
0586: /**
0587: * INTERNAL:
0588: * The returns if the mapping has any constraint dependencies, such as foreign keys and join tables.
0589: */
0590: public boolean hasConstraintDependency() {
0591: return false;
0592: }
0593:
0594: /**
0595: * PUBLIC:
0596: * Return if method access is used.
0597: */
0598: public boolean isUsingMethodAccess() {
0599: return getAttributeAccessor() instanceof MethodAttributeAccessor;
0600: }
0601:
0602: /**
0603: * INTERNAL:
0604: * Return if the mapping has any ownership or other dependency over its target object(s).
0605: */
0606: public boolean hasDependency() {
0607: return isPrivateOwned();
0608: }
0609:
0610: /**
0611: * INTERNAL:
0612: * The returns if the mapping has any inverse constraint dependencies, such as foreign keys and join tables.
0613: */
0614: public boolean hasInverseConstraintDependency() {
0615: return false;
0616: }
0617:
0618: /**
0619: * INTERNAL:
0620: * Allow for initialization of properties and validation.
0621: */
0622: public void initialize(AbstractSession session)
0623: throws DescriptorException {
0624: ;
0625: }
0626:
0627: /**
0628: * INTERNAL:
0629: * Related mapping should implement this method to return true.
0630: */
0631: public boolean isAggregateCollectionMapping() {
0632: return false;
0633: }
0634:
0635: /**
0636: * INTERNAL:
0637: * Related mapping should implement this method to return true.
0638: */
0639: public boolean isAggregateMapping() {
0640: return false;
0641: }
0642:
0643: /**
0644: * INTERNAL:
0645: * Related mapping should implement this method to return true.
0646: */
0647: public boolean isAggregateObjectMapping() {
0648: return false;
0649: }
0650:
0651: /**
0652: * INTERNAL:
0653: * Related mapping should implement this method to return true.
0654: */
0655: public boolean isCollectionMapping() {
0656: return false;
0657: }
0658:
0659: /**
0660: * INTERNAL:
0661: */
0662: public boolean isDatabaseMapping() {
0663: return true;
0664: }
0665:
0666: /**
0667: * INTERNAL:
0668: * Related mapping should implement this method to return true.
0669: */
0670: public boolean isDirectCollectionMapping() {
0671: return false;
0672: }
0673:
0674: /**
0675: * INTERNAL:
0676: * Related mapping should implement this method to return true.
0677: */
0678: public boolean isDirectMapMapping() {
0679: return false;
0680: }
0681:
0682: /**
0683: * INTERNAL:
0684: * Related mapping should implement this method to return true.
0685: */
0686: public boolean isDirectToFieldMapping() {
0687: return false;
0688: }
0689:
0690: /**
0691: * INTERNAL:
0692: * Related mapping should implement this method to return true.
0693: */
0694: public boolean isForeignReferenceMapping() {
0695: return false;
0696: }
0697:
0698: /**
0699: * INTERNAL:
0700: * Related mapping should implement this method to return true.
0701: */
0702: public boolean isManyToManyMapping() {
0703: return false;
0704: }
0705:
0706: /**
0707: * INTERNAL:
0708: * Related mapping should implement this method to return true.
0709: */
0710: public boolean isNestedTableMapping() {
0711: return false;
0712: }
0713:
0714: /**
0715: * INTERNAL:
0716: * Related mapping should implement this method to return true.
0717: */
0718: public boolean isObjectReferenceMapping() {
0719: return false;
0720: }
0721:
0722: /**
0723: * INTERNAL:
0724: * Related mapping should implement this method to return true.
0725: */
0726: public boolean isObjectTypeMapping() {
0727: return false;
0728: }
0729:
0730: /**
0731: * INTERNAL:
0732: * Related mapping should implement this method to return true.
0733: */
0734: public boolean isOneToManyMapping() {
0735: return false;
0736: }
0737:
0738: /**
0739: * INTERNAL:
0740: * Related mapping should implement this method to return true.
0741: */
0742: public boolean isOneToOneMapping() {
0743: return false;
0744: }
0745:
0746: /**
0747: * INTERNAL:
0748: * Return whether the value of this mapping is optional (that is, can be
0749: * null). This is a hint and is used when generating DDL. It should be
0750: * disregarded for primitive types.
0751: */
0752: public boolean isOptional() {
0753: return isOptional;
0754: }
0755:
0756: /**
0757: * INTERNAL:
0758: * All EIS mappings should implement this method to return true.
0759: */
0760: public boolean isEISMapping() {
0761: return false;
0762: }
0763:
0764: /**
0765: * INTERNAL:
0766: * All relational mappings should implement this method to return true.
0767: */
0768: public boolean isRelationalMapping() {
0769: return false;
0770: }
0771:
0772: /**
0773: * INTERNAL:
0774: * All relational mappings should implement this method to return true.
0775: */
0776: public boolean isXMLMapping() {
0777: return false;
0778: }
0779:
0780: /**
0781: * INTERNAL:
0782: * Related mapping should implement this method to return true.
0783: */
0784: public boolean isAbstractDirectMapping() {
0785: return false;
0786: }
0787:
0788: /**
0789: * INTERNAL:
0790: * Related mapping should implement this method to return true.
0791: */
0792: public boolean isAbstractCompositeDirectCollectionMapping() {
0793: return false;
0794: }
0795:
0796: /**
0797: * INTERNAL:
0798: * Related mapping should implement this method to return true.
0799: */
0800: public boolean isAbstractCompositeObjectMapping() {
0801: return false;
0802: }
0803:
0804: /**
0805: * INTERNAL:
0806: * Related mapping should implement this method to return true.
0807: */
0808: public boolean isAbstractCompositeCollectionMapping() {
0809: return false;
0810: }
0811:
0812: /**
0813: * INTERNAL:
0814: * Return if this mapping support joining.
0815: */
0816: public boolean isJoiningSupported() {
0817: return false;
0818: }
0819:
0820: /**
0821: * INTERNAL:
0822: * Return if this mapping requires its attribute value to be cloned.
0823: */
0824: public boolean isCloningRequired() {
0825: return true;
0826: }
0827:
0828: /**
0829: * INTERNAL:
0830: * Set by the Object builder during initialization returns true if this mapping
0831: * is used as a primary key mapping.
0832: */
0833: public boolean isPrimaryKeyMapping() {
0834: return this .primaryKeyMapping;
0835: }
0836:
0837: /**
0838: * INTERNAL:
0839: * Used when determining if a mapping supports cascaded version optimistic
0840: * locking.
0841: */
0842: public boolean isCascadedLockingSupported() {
0843: return false;
0844: }
0845:
0846: /**
0847: * INTERNAL:
0848: * Return if this mapping supports change tracking.
0849: */
0850: public boolean isChangeTrackingSupported() {
0851: return false;
0852: }
0853:
0854: /**
0855: * INTERNAL:
0856: * Return if the mapping has ownership over its target object(s).
0857: */
0858: public boolean isPrivateOwned() {
0859: return false;
0860: }
0861:
0862: /**
0863: * INTERNAL:
0864: * Returns true if mapping is read only else false.
0865: */
0866: public boolean isReadOnly() {
0867: return isReadOnly;
0868: }
0869:
0870: /**
0871: * INTERNAL:
0872: * Related mapping should implement this method to return true.
0873: */
0874: public boolean isReferenceMapping() {
0875: return false;
0876: }
0877:
0878: protected boolean isRemotelyInitialized() {
0879: return isRemotelyInitialized;
0880: }
0881:
0882: /**
0883: * INTERNAL:
0884: * Related mapping should implement this method to return true.
0885: */
0886: public boolean isSerializedObjectMapping() {
0887: return false;
0888: }
0889:
0890: /**
0891: * INTERNAL:
0892: * Related mapping should implement this method to return true.
0893: */
0894: public boolean isStructureMapping() {
0895: return false;
0896: }
0897:
0898: /**
0899: * INTERNAL:
0900: * Related mapping should implement this method to return true.
0901: */
0902: public boolean isTransformationMapping() {
0903: return false;
0904: }
0905:
0906: /**
0907: * INTERNAL:
0908: * Related mapping should implement this method to return true.
0909: */
0910: public boolean isTypeConversionMapping() {
0911: return false;
0912: }
0913:
0914: /**
0915: * INTERNAL:
0916: * Related mapping should implement this method to return true.
0917: */
0918: public boolean isVariableOneToOneMapping() {
0919: return false;
0920: }
0921:
0922: /**
0923: * INTERNAL:
0924: * Related mapping should implement this method to return true.
0925: */
0926: public boolean isDirectToXMLTypeMapping() {
0927: return false;
0928: }
0929:
0930: /**
0931: * INTERNAL:
0932: * Some mappings support no attribute (transformation).
0933: */
0934: public boolean isWriteOnly() {
0935: return false;
0936: }
0937:
0938: /**
0939: * INTERNAL:
0940: * Iterate on the appropriate attribute value.
0941: */
0942: public abstract void iterate(DescriptorIterator iterator);
0943:
0944: /**
0945: * INTERNAL:
0946: * Iterate on the attribute value.
0947: * The value holder has already been processed.
0948: */
0949: public void iterateOnRealAttributeValue(
0950: DescriptorIterator iterator, Object realAttributeValue) {
0951: throw DescriptorException.invalidMappingOperation(this ,
0952: "iterateOnRealAttributeValue");
0953: }
0954:
0955: /**
0956: * INTERNAL:
0957: * Merge changes from the source to the target object.
0958: */
0959: public abstract void mergeChangesIntoObject(Object target,
0960: ChangeRecord changeRecord, Object source,
0961: MergeManager mergeManager);
0962:
0963: /**
0964: * INTERNAL:
0965: * Merge changes from the source to the target object.
0966: */
0967: public abstract void mergeIntoObject(Object target,
0968: boolean isTargetUninitialized, Object source,
0969: MergeManager mergeManager);
0970:
0971: /**
0972: * INTERNAL:
0973: * Perform the commit event.
0974: * This is used in the uow to delay data modifications.
0975: */
0976: public void performDataModificationEvent(Object[] event,
0977: AbstractSession session) throws DatabaseException,
0978: DescriptorException {
0979: throw DescriptorException.invalidDataModificationEvent(this );
0980: }
0981:
0982: /**
0983: * INTERNAL:
0984: * A subclass should implement this method if it wants different behaviour.
0985: * Recurse thru the parts to delete the reference objects after the actual object is deleted.
0986: */
0987: public void postDelete(WriteObjectQuery query)
0988: throws DatabaseException {
0989: return;
0990: }
0991:
0992: /**
0993: * INTERNAL:
0994: * Allow for initialization of properties and validation that have dependecies no the descriptor
0995: * being initialized.
0996: */
0997: public void postInitialize(AbstractSession session)
0998: throws DescriptorException {
0999: // Nothing by default.
1000: }
1001:
1002: /**
1003: * INTERNAL:
1004: * A subclass should implement this method if it wants different behaviour.
1005: * Recurse thru the parts to insert the reference objects after the actual object is inserted.
1006: */
1007: public void postInsert(WriteObjectQuery query)
1008: throws DatabaseException {
1009: return;
1010: }
1011:
1012: /**
1013: * INTERNAL:
1014: * A subclass should implement this method if it wants different behaviour.
1015: * Recurse thru the parts to update the reference objects after the actual object is updated.
1016: */
1017: public void postUpdate(WriteObjectQuery query)
1018: throws DatabaseException {
1019: return;
1020: }
1021:
1022: /**
1023: * INTERNAL:
1024: * A subclass should implement this method if it wants different behaviour.
1025: * Recurse thru the parts to delete the reference objects before the actual object is deleted.
1026: */
1027: public void preDelete(WriteObjectQuery query)
1028: throws DatabaseException {
1029: return;
1030: }
1031:
1032: /**
1033: * INTERNAL:
1034: * Allow for initialization of properties and validation.
1035: */
1036: public void preInitialize(AbstractSession session)
1037: throws DescriptorException {
1038: try {
1039: getAttributeAccessor().initializeAttributes(
1040: getDescriptor().getJavaClass());
1041: } catch (DescriptorException exception) {
1042: exception.setMapping(this );
1043: session.getIntegrityChecker().handleError(exception);
1044: }
1045: }
1046:
1047: /**
1048: * INTERNAL:
1049: * A subclass should implement this method if it wants different behaviour.
1050: * Recurse thru the parts to insert the reference objects before the actual object is inserted.
1051: */
1052: public void preInsert(WriteObjectQuery query)
1053: throws DatabaseException {
1054: return;
1055: }
1056:
1057: /**
1058: * INTERNAL:
1059: * A subclass that supports cascade version optimistic locking should
1060: * implement this method to properly prepare the locking policy for their
1061: * mapping type.
1062: */
1063: public void prepareCascadeLockingPolicy() {
1064: return;
1065: }
1066:
1067: /**
1068: * INTERNAL:
1069: * A subclass should implement this method if it wants different behaviour.
1070: * Recurse thru the parts to update the reference objects before the actual object is updated.
1071: */
1072: public void preUpdate(WriteObjectQuery query)
1073: throws DatabaseException {
1074: return;
1075: }
1076:
1077: /**
1078: * INTERNAL:
1079: * Extract value from the row and set the attribute to this value in the object.
1080: * return value as this value will have been converted to the appropriate type for
1081: * the object.
1082: */
1083: public Object readFromRowIntoObject(AbstractRecord databaseRow,
1084: JoinedAttributeManager joinManager, Object targetObject,
1085: ObjectBuildingQuery sourceQuery) throws DatabaseException {
1086: // This version can be called directly for reading a sequence number
1087: // field, a write lock value, or a return row into an object, and hence
1088: // the query is just a placeholder. Getting the correct execution
1089: // session will generate an exception, so just pass in any session.
1090: // In general call this version only if no field conversion needed.
1091: return readFromRowIntoObject(databaseRow, joinManager,
1092: targetObject, sourceQuery, sourceQuery.getSession());
1093: }
1094:
1095: /**
1096: * INTERNAL:
1097: * Extract value from the row and set the attribute to this value in the object.
1098: * return value as this value will have been converted to the appropriate type for
1099: * the object.
1100: */
1101: public Object readFromRowIntoObject(AbstractRecord databaseRow,
1102: JoinedAttributeManager joinManager, Object targetObject,
1103: ObjectBuildingQuery sourceQuery,
1104: AbstractSession executionSession) throws DatabaseException {
1105: Object attributeValue = valueFromRow(databaseRow, joinManager,
1106: sourceQuery, executionSession);
1107: setAttributeValueInObject(targetObject, attributeValue);
1108: return attributeValue;
1109: }
1110:
1111: /**
1112: * PUBLIC:
1113: * To make mapping read only.
1114: * Read-only mappings can be used if two attributes map to the same field.
1115: * Read-only mappings cannot be used for the primary key or other required fields.
1116: */
1117: public void readOnly() {
1118: setIsReadOnly(true);
1119: }
1120:
1121: /**
1122: * PUBLIC:
1123: * The mapping can be dynamically made either readOnly or readWriteOnly. This makes mapping go back to
1124: * default mode.
1125: */
1126: public void readWrite() {
1127: setIsReadOnly(false);
1128: }
1129:
1130: /**
1131: * INTERNAL:
1132: * Rehash any hashtables based on fields.
1133: * This is used to clone descriptors for aggregates, which hammer field names,
1134: * it is probably better not to hammer the field name and this should be refactored.
1135: */
1136: public void rehashFieldDependancies(AbstractSession session) {
1137: // Should be overwritten by any mapping with fields.
1138: }
1139:
1140: /**
1141: * ADVANCED:
1142: * Set the attributeAccessor.
1143: * The attribute accessor is responsible for setting and retrieving the attribute value
1144: * from the object for this mapping.
1145: * This can be set to an implementor of AttributeAccessor if the attribute
1146: * requires advanced conversion of the mapping value, or a real attribute does not exist.
1147: */
1148: public void setAttributeAccessor(AttributeAccessor attributeAccessor) {
1149: String attributeName = getAttributeName();
1150: this .attributeAccessor = attributeAccessor;
1151: if (attributeAccessor.getAttributeName() == null) {
1152: attributeAccessor.setAttributeName(attributeName);
1153: }
1154: }
1155:
1156: /**
1157: * PUBLIC:
1158: * Sets the name of the attribute in the mapping.
1159: */
1160: public void setAttributeName(String attributeName) {
1161: getAttributeAccessor().setAttributeName(attributeName);
1162: }
1163:
1164: /**
1165: * INTERNAL:
1166: * Set the value of the attribute mapped by this mapping.
1167: */
1168: public void setAttributeValueInObject(Object object, Object value)
1169: throws DescriptorException {
1170: // PERF: Direct variable access.
1171: try {
1172: this .attributeAccessor.setAttributeValueInObject(object,
1173: value);
1174: } catch (DescriptorException exception) {
1175: exception.setMapping(this );
1176: throw exception;
1177: }
1178: }
1179:
1180: /**
1181: * INTERNAL:
1182: * Set the value of the attribute mapped by this mapping,
1183: * placing it inside a value holder if necessary.
1184: */
1185: public void setRealAttributeValueInObject(Object object,
1186: Object value) throws DescriptorException {
1187: try {
1188: this .setAttributeValueInObject(object, value);
1189: } catch (DescriptorException exception) {
1190: exception.setMapping(this );
1191: throw exception;
1192: }
1193: }
1194:
1195: /**
1196: * INTERNAL:
1197: * Set the descriptor to which this mapping belongs
1198: */
1199: public void setDescriptor(ClassDescriptor descriptor) {
1200: this .descriptor = descriptor;
1201: }
1202:
1203: /**
1204: * INTERNAL:
1205: * Set the mapping's field collection.
1206: */
1207: protected void setFields(Vector<DatabaseField> fields) {
1208: this .fields = fields;
1209: }
1210:
1211: /**
1212: * PUBLIC:
1213: * This method is invoked reflectively on the reference object to return the value of the
1214: * attribute in the object. This method sets the name of the getMethodName.
1215: */
1216: public void setGetMethodName(String methodName) {
1217: if (methodName == null) {
1218: return;
1219: }
1220:
1221: // This is done because setting attribute name by defaults create InstanceVariableAttributeAccessor
1222: if (getAttributeAccessor() instanceof InstanceVariableAttributeAccessor) {
1223: String attributeName = this .attributeAccessor
1224: .getAttributeName();
1225: setAttributeAccessor(new MethodAttributeAccessor());
1226: getAttributeAccessor().setAttributeName(attributeName);
1227: }
1228:
1229: ((MethodAttributeAccessor) getAttributeAccessor())
1230: .setGetMethodName(methodName);
1231: }
1232:
1233: /**
1234: * INTERNAL:
1235: * Used to specify whether the value of this mapping may be null. It is
1236: * used when generating DDL.
1237: */
1238: public void setIsOptional(boolean isOptional) {
1239: this .isOptional = isOptional;
1240: }
1241:
1242: /**
1243: * INTERNAL:
1244: * Set by the Object builder during initialization returns true if this mapping
1245: * is used as a primary key mapping.
1246: */
1247: public void setIsPrimaryKeyMapping(boolean pkMapping) {
1248: this .primaryKeyMapping = pkMapping;
1249: }
1250:
1251: /**
1252: * PUBLIC:
1253: * Set this mapping to be read only.
1254: * Read-only mappings can be used if two attributes map to the same field.
1255: * Read-only mappings cannot be used for the primary key or other required fields.
1256: */
1257: public void setIsReadOnly(boolean aBoolean) {
1258: isReadOnly = aBoolean;
1259: }
1260:
1261: /**
1262: * INTERNAL:
1263: * used as a temporary store for custom SDK usage
1264: */
1265: public void setProperties(Map properties) {
1266: this .properties = properties;
1267: }
1268:
1269: /**
1270: * ADVANCED:
1271: * Allow user defined properties.
1272: */
1273: public void setProperty(Object property, Object value) {
1274: getProperties().put(property, value);
1275: }
1276:
1277: /**
1278: * PUBLIC:
1279: * This method is invoked reflectively on the reference object to get the value of the attribute.
1280: * The method defined on the object should actually return the value that needs to be set in the
1281: * attribute accessor.
1282: */
1283: public void setSetMethodName(String methodName) {
1284: if (methodName == null) {
1285: return;
1286: }
1287:
1288: // This is done because setting attribute name by defaults create InstanceVariableAttributeAccessor
1289: if (!(getAttributeAccessor() instanceof MethodAttributeAccessor)) {
1290: String attributeName = this .attributeAccessor
1291: .getAttributeName();
1292: setAttributeAccessor(new MethodAttributeAccessor());
1293: getAttributeAccessor().setAttributeName(attributeName);
1294: }
1295:
1296: ((MethodAttributeAccessor) getAttributeAccessor())
1297: .setSetMethodName(methodName);
1298: }
1299:
1300: /**
1301: * ADVANCED:
1302: * Set the weight of the mapping, used to sort mappings
1303: * DirectToField Mappings have a default weight of 1 while all other Mappings have a
1304: * default weight of MAXINT. Ordering of Mappings can be achieved by setting the weight of
1305: * a particular mapping to a value within the above mentioned limits. By ordering mappings
1306: * the user can control what order relationships are processed by TopLink.
1307: */
1308:
1309: // CR 4097
1310: public void setWeight(Integer newWeight) {
1311: this .weight = newWeight;
1312: }
1313:
1314: /**
1315: * ADVANCED:
1316: * This method is used to add an object to a collection once the changeSet is applied.
1317: * The referenceKey parameter should only be used for direct Maps.
1318: */
1319: public void simpleAddToCollectionChangeRecord(Object referenceKey,
1320: Object changeSetToAdd, ObjectChangeSet changeSet,
1321: AbstractSession session) throws DescriptorException {
1322: throw DescriptorException.invalidMappingOperation(this ,
1323: "simpleAddToCollectionChangeRecord");
1324: }
1325:
1326: /**
1327: * ADVANCED:
1328: * This method is used to remove an object from a collection once the changeSet is applied.
1329: * The referenceKey parameter should only be used for direct Maps.
1330: */
1331: public void simpleRemoveFromCollectionChangeRecord(
1332: Object referenceKey, Object changeSetToAdd,
1333: ObjectChangeSet changeSet, AbstractSession session)
1334: throws DescriptorException {
1335: throw DescriptorException.invalidMappingOperation(this ,
1336: "simpleRemoveFromCollectionChangeRecord");
1337: }
1338:
1339: /**
1340: * INTERNAL:
1341: * Print the mapping attribute name, this is used in error messages.
1342: */
1343: public String toString() {
1344: return getClass().getName() + "[" + getAttributeName() + "]";
1345: }
1346:
1347: /**
1348: * INTERNAL:
1349: * Allow for subclasses to perform validation.
1350: */
1351: public void validateAfterInitialization(AbstractSession session)
1352: throws DescriptorException {
1353: }
1354:
1355: /**
1356: * INTERNAL:
1357: * Allow for subclasses to perform validation.
1358: */
1359: public void validateBeforeInitialization(AbstractSession session)
1360: throws DescriptorException {
1361: }
1362:
1363: /**
1364: * INTERNAL:
1365: * A subclass should extract the value from the object for the field, if it does not map the field then
1366: * it should return null.
1367: * Return the Value from the object.
1368: */
1369: public Object valueFromObject(Object anObject, DatabaseField field,
1370: AbstractSession session) {
1371: return null;
1372: }
1373:
1374: /**
1375: * INTERNAL:
1376: * A subclass should implement this method if it wants different behaviour.
1377: * Returns the value for the mapping from the database row.
1378: */
1379: public Object valueFromRow(AbstractRecord row,
1380: JoinedAttributeManager joinManager,
1381: ObjectBuildingQuery query) throws DatabaseException {
1382: return valueFromRow(row, joinManager, query, query.getSession()
1383: .getExecutionSession(query));
1384: }
1385:
1386: /**
1387: * INTERNAL:
1388: *
1389: */
1390: public Object valueFromRow(AbstractRecord row,
1391: JoinedAttributeManager joinManager,
1392: ObjectBuildingQuery query, AbstractSession session)
1393: throws DatabaseException {
1394: return null;
1395: }
1396:
1397: /**
1398: * INTERNAL:
1399: * To verify if the specified object has been deleted or not.
1400: */
1401: public boolean verifyDelete(Object object, AbstractSession session)
1402: throws DatabaseException {
1403: return true;
1404: }
1405:
1406: /**
1407: * INTERNAL:
1408: * A subclass should implement this method if it wants different behaviour.
1409: * Write the foreign key values from the attribute to the row.
1410: */
1411:
1412: public void writeFromAttributeIntoRow(Object attribute,
1413: AbstractRecord row, AbstractSession session) {
1414: // Do nothing by default.
1415: }
1416:
1417: /**
1418: * INTERNAL:
1419: * A subclass should implement this method if it wants different behaviour.
1420: * Write the attribute value from the object to the row.
1421: */
1422: public void writeFromObjectIntoRow(Object object,
1423: AbstractRecord row, AbstractSession session) {
1424: // Do nothing by default.
1425: }
1426:
1427: /**
1428: * INTERNAL:
1429: * This row is built for shallow insert which happens in case of of circular dependencies bidirectional inserts.
1430: */
1431: public void writeFromObjectIntoRowForShallowInsert(Object object,
1432: AbstractRecord row, AbstractSession session) {
1433: writeFromObjectIntoRow(object, row, session);
1434: }
1435:
1436: /**
1437: * INTERNAL:
1438: * This row is built for shallow delete which happens in case of circular dependencies for bidirectional deletes.
1439: */
1440: public void writeFromObjectIntoRowForShallowDelete(Object object,
1441: AbstractRecord row, AbstractSession session) {
1442: // Do nothing by default.
1443: }
1444:
1445: /**
1446: * INTERNAL:
1447: * A subclass should implement this method if it wants different behaviour.
1448: * Write the attribute value from the object to the row.
1449: */
1450: public void writeFromObjectIntoRowWithChangeRecord(
1451: ChangeRecord changeRecord, AbstractRecord row,
1452: AbstractSession session) {
1453: // Do nothing by default.
1454: }
1455:
1456: /**
1457: * INTERNAL:
1458: * This row is built for shallow insert which happens in case of bidirectional inserts.
1459: */
1460: public void writeFromObjectIntoRowForShallowInsertWithChangeRecord(
1461: ChangeRecord changeRecord, AbstractRecord row,
1462: AbstractSession session) {
1463: writeFromObjectIntoRowWithChangeRecord(changeRecord, row,
1464: session);
1465: }
1466:
1467: /**
1468: * INTERNAL:
1469: * Write the attribute value from the object to the row for update.
1470: */
1471: public void writeFromObjectIntoRowForUpdate(WriteObjectQuery query,
1472: AbstractRecord row) {
1473: writeFromObjectIntoRow(query.getObject(), row, query
1474: .getSession());
1475: }
1476:
1477: /**
1478: * INTERNAL:
1479: * A subclass should implement this method if it wants different behaviour.
1480: * Write the attribute value from the object to the row.
1481: */
1482: public void writeFromObjectIntoRowForWhereClause(
1483: ObjectLevelModifyQuery query, AbstractRecord row) {
1484: Object object;
1485: if (query.isDeleteObjectQuery()) {
1486: object = query.getObject();
1487: } else {
1488: object = query.getBackupClone();
1489: }
1490: writeFromObjectIntoRow(object, row, query.getSession());
1491: }
1492:
1493: /**
1494: * INTERNAL:
1495: * Write fields needed for insert into the template for with null values.
1496: */
1497: public void writeInsertFieldsIntoRow(AbstractRecord databaseRow,
1498: AbstractSession session) {
1499: // Do nothing by default.
1500: }
1501:
1502: /**
1503: * INTERNAL:
1504: * Write fields needed for update into the template for with null values.
1505: * By default inserted fields are used.
1506: */
1507: public void writeUpdateFieldsIntoRow(AbstractRecord databaseRow,
1508: AbstractSession session) {
1509: writeInsertFieldsIntoRow(databaseRow, session);
1510: }
1511:
1512: /**
1513: * INTERNAL:
1514: * Either create a new change record or update the change record with the new value.
1515: * This is used by attribute change tracking.
1516: */
1517: public void updateChangeRecord(Object clone, Object newValue,
1518: Object oldValue, ObjectChangeSet objectChangeSet,
1519: UnitOfWorkImpl uow) throws DescriptorException {
1520: throw DescriptorException.invalidMappingOperation(this ,
1521: "updateChangeRecord");
1522: }
1523:
1524: /**
1525: * INTERNAL:
1526: * Add a new value and its change set to the collection change record. This is used by
1527: * attribute change tracking.
1528: */
1529: public void addToCollectionChangeRecord(Object newKey,
1530: Object newValue, ObjectChangeSet objectChangeSet,
1531: UnitOfWorkImpl uow) throws DescriptorException {
1532: throw DescriptorException.invalidMappingOperation(this ,
1533: "addToCollectionChangeRecord");
1534: }
1535:
1536: /**
1537: * INTERNAL:
1538: * Remove a value and its change set from the collection change record. This is used by
1539: * attribute change tracking.
1540: */
1541: public void removeFromCollectionChangeRecord(Object newKey,
1542: Object newValue, ObjectChangeSet objectChangeSet,
1543: UnitOfWorkImpl uow) throws DescriptorException {
1544: throw DescriptorException.invalidMappingOperation(this ,
1545: "removeFromCollectionChangeRecord");
1546: }
1547:
1548: /**
1549: * INTERNAL:
1550: * Directly build a change record without comparison
1551: */
1552: public ChangeRecord buildChangeRecord(Object newValue,
1553: ObjectChangeSet owner, AbstractSession session)
1554: throws DescriptorException {
1555: throw DescriptorException.invalidMappingOperation(this ,
1556: "buildChangeRecord");
1557: }
1558: }
|