KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > mappings > DatabaseMapping


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.mappings;
23
24 import java.io.*;
25 import java.util.*;
26 import oracle.toplink.essentials.descriptors.ClassDescriptor;
27 import oracle.toplink.essentials.exceptions.*;
28 import oracle.toplink.essentials.expressions.*;
29 import oracle.toplink.essentials.indirection.*;
30 import oracle.toplink.essentials.internal.descriptors.*;
31 import oracle.toplink.essentials.internal.expressions.*;
32 import oracle.toplink.essentials.internal.helper.*;
33 import oracle.toplink.essentials.internal.indirection.*;
34 import oracle.toplink.essentials.internal.queryframework.*;
35 import oracle.toplink.essentials.internal.sessions.*;
36 import oracle.toplink.essentials.queryframework.*;
37 import oracle.toplink.essentials.sessions.ObjectCopyingPolicy;
38 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
39 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
40 import oracle.toplink.essentials.internal.sessions.AbstractSession;
41
42 /**
43  * <p><b>Purpose</b>: Defines how an attribute of an object maps to and from the database
44  *
45  * <p><b>Responsibilities</b>:<ul>
46  * <li> Define type of relationship (1:1/1:M/M:M/etc.)
47  * <li> Define instance variable name and fields names required
48  * <li> Define any additional properties (ownership, indirection, read only, etc.)
49  * <li> Control building the value for the instance variable from the database row
50  * <li> Control building the database fields from the object
51  * <li> Control any pre/post updating/inserting/deleting required to maintain the relationship
52  * <li> Merges object changes for unit of work.
53  * <li> Clones objects for unit of work.
54  * <li> cache computed information to optimize performance
55  * </ul>
56  *
57  * @author Sati
58  * @since TOPLink/Java 1.0
59  */

60 public abstract class DatabaseMapping implements Cloneable JavaDoc, Serializable {
61
62     /** Used to reduce memory for mappings with no fields. */
63     protected static Vector NO_FIELDS = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(0);
64
65     /** Used to share integer instance to reduce memory. */
66     protected static Integer JavaDoc NO_WEIGHT = new Integer JavaDoc(Integer.MAX_VALUE);
67     protected static Integer JavaDoc WEIGHT_1 = new Integer JavaDoc(1);
68
69     /** Descriptor to which this mapping belongs to */
70     protected ClassDescriptor descriptor;
71
72     /** Wrapper to store the reference objects. */
73     protected AttributeAccessor attributeAccessor;
74
75     /** Makes this mapping read only. No write are performed on it. Default is false */
76     protected boolean isReadOnly;
77     
78     /** Specifies whether this mapping is optional (i.e. field may be null). Used for DDL generation. */
79     protected boolean isOptional;
80
81     /** Fields associated with the mappings are cached */
82     protected Vector fields;
83
84     /** It is needed only in remote initialization and mapping is in parent descriptor */
85     protected boolean isRemotelyInitialized;
86
87     /** This is a TopLink defined attribute that allows us to sort the mappings */
88     protected Integer JavaDoc weight = NO_WEIGHT;
89
90     /** used as a temporary store for custom SDK usage */
91     protected Map properties;
92
93     /** used as a quick check to see if this mapping is a primary key mapping,
94      * set by the object builder during initialization.
95      */

96     protected boolean primaryKeyMapping = false;
97
98     /**
99      * PUBLIC:
100      * Default constructor.
101      */

102     public DatabaseMapping() {
103         this.isOptional = true;
104         this.isReadOnly = false;
105         this.attributeAccessor = new InstanceVariableAttributeAccessor();
106     }
107
108     /**
109      * INTERNAL:
110      * Clone the attribute from the clone and assign it to the backup.
111      */

112     public abstract void buildBackupClone(Object JavaDoc clone, Object JavaDoc backup, UnitOfWorkImpl unitOfWork);
113
114     /**
115      * INTERNAL:
116      * Require for cloning, the part must be cloned.
117      */

118     public Object JavaDoc buildBackupCloneForPartObject(Object JavaDoc attributeValue, Object JavaDoc clone, Object JavaDoc backup, UnitOfWorkImpl unitOfWork) {
119         throw DescriptorException.invalidMappingOperation(this, "buildBackupCloneForPartObject");
120     }
121
122     /**
123      * INTERNAL:
124      * Clone the attribute from the original and assign it to the clone.
125      */

126     public abstract void buildClone(Object JavaDoc original, Object JavaDoc clone, UnitOfWorkImpl unitOfWork, JoinedAttributeManager joinedAttributeManager);
127
128     /**
129      * INTERNAL:
130      * A combination of readFromRowIntoObject and buildClone.
131      * <p>
132      * buildClone assumes the attribute value exists on the original and can
133      * simply be copied.
134      * <p>
135      * readFromRowIntoObject assumes that one is building an original.
136      * <p>
137      * Both of the above assumptions are false in this method, and actually
138      * attempts to do both at the same time.
139      * <p>
140      * Extract value from the row and set the attribute to this value in the
141      * working copy clone.
142      * In order to bypass the shared cache when in transaction a UnitOfWork must
143      * be able to populate working copies directly from the row.
144      */

145     public abstract void buildCloneFromRow(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object JavaDoc clone, ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork, AbstractSession executionSession);
146
147     /**
148      * INTERNAL:
149      * Builds a shallow original object. Only direct attributes and primary
150      * keys are populated. In this way the minimum original required for
151      * instantiating a working copy clone can be built without placing it in
152      * the shared cache (no concern over cycles).
153      */

154     public void buildShallowOriginalFromRow(AbstractRecord databaseRow, Object JavaDoc original, ObjectBuildingQuery query, AbstractSession executionSession) {
155         return;
156     }
157
158     /**
159      * INTERNAL:
160      * Require for cloning, the part must be cloned.
161      */

162     public Object JavaDoc buildCloneForPartObject(Object JavaDoc attributeValue, Object JavaDoc original, Object JavaDoc clone, UnitOfWorkImpl unitOfWork, boolean isExisting) {
163         throw DescriptorException.invalidMappingOperation(this, "buildCloneForPartObject");
164     }
165
166     /**
167      * INTERNAL:
168      * Copy of the attribute of the object.
169      * This is NOT used for unit of work but for templatizing an object.
170      */

171     public void buildCopy(Object JavaDoc copy, Object JavaDoc original, ObjectCopyingPolicy policy) {
172     }
173
174     /**
175      * INTERNAL:
176      * Used to allow object level comparisons.
177      */

178     public Expression buildObjectJoinExpression(Expression base, Object JavaDoc value, AbstractSession session) {
179         throw QueryException.unsupportedMappingForObjectComparison(this, base);
180     }
181
182     /**
183      * INTERNAL:
184      * Used to allow object level comparisons.
185      */

186     public Expression buildObjectJoinExpression(Expression base, Expression argument, AbstractSession session) {
187         throw QueryException.unsupportedMappingForObjectComparison(this, base);
188     }
189
190     /**
191      * INTERNAL:
192      * Cascade registerNew for Create through mappings that require the cascade
193      */

194     abstract public void cascadePerformRemoveIfRequired(Object JavaDoc object, UnitOfWorkImpl uow, IdentityHashtable visitedObjects);
195
196     /**
197      * INTERNAL:
198      * Cascade registerNew for Create through mappings that require the cascade
199      */

200     abstract public void cascadeRegisterNewIfRequired(Object JavaDoc object, UnitOfWorkImpl uow, IdentityHashtable visitedObjects);
201
202     /**
203      * INTERNAL:
204      * Used by AttributeLevelChangeTracking to update a changeRecord with calculated changes
205      * as apposed to detected changes. If an attribute can not be change tracked it's
206      * changes can be detected through this process.
207      */

208     public void calculateDeferredChanges(ChangeRecord changeRecord, AbstractSession session){
209         throw DescriptorException.invalidMappingOperation(this, "calculatedDeferredChanges");
210     }
211     
212     /**
213      * INTERNAL:
214      * Cascade the merge to the component object, if appropriate.
215      */

216     public void cascadeMerge(Object JavaDoc sourceElement, MergeManager mergeManager) {
217         throw DescriptorException.invalidMappingOperation(this, "cascadeMerge");
218     }
219
220     /**
221      * INTERNAL:
222      * Clones itself.
223      */

224     public Object JavaDoc clone() {
225         // Bug 3037701 - clone the AttributeAccessor
226
DatabaseMapping mapping = null;
227         try {
228             mapping = (DatabaseMapping)super.clone();
229         } catch (CloneNotSupportedException JavaDoc e) {
230             throw new InternalError JavaDoc();
231         }
232         mapping.setAttributeAccessor((AttributeAccessor)attributeAccessor.clone());
233         return mapping;
234     }
235
236     /**
237      * INTERNAL:
238      * Helper method to clone vector of fields (used in aggregate initialization cloning).
239      */

240     protected Vector cloneFields(Vector fields) {
241         Vector clonedFields = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance();
242         for (Enumeration fieldsEnum = fields.elements(); fieldsEnum.hasMoreElements();) {
243             clonedFields.addElement(((DatabaseField)fieldsEnum.nextElement()).clone());
244         }
245
246         return clonedFields;
247     }
248
249     /**
250      * This method must be overwritten in the subclasses to return a vector of all the
251      * fields this mapping represents.
252      */

253     protected Vector collectFields() {
254         return NO_FIELDS;
255     }
256
257     /**
258      * INTERNAL:
259      * This method was created in VisualAge.
260      * @return prototype.changeset.ChangeRecord
261      */

262     abstract public ChangeRecord compareForChange(Object JavaDoc clone, Object JavaDoc backup, ObjectChangeSet owner, AbstractSession session);
263
264     /**
265      * INTERNAL:
266      * Compare the attributes belonging to this mapping for the objects.
267      */

268     public abstract boolean compareObjects(Object JavaDoc firstObject, Object JavaDoc secondObject, AbstractSession session);
269
270     /**
271      * INTERNAL:
272      * Convert all the class-name-based settings in this mapping to actual class-based
273      * settings
274      * This method is implemented by subclasses as necessary.
275      * @param classLoader
276      */

277     public void convertClassNamesToClasses(ClassLoader JavaDoc classLoader){};
278
279     /**
280      * INTERNAL:
281      * Builder the unit of work value holder.
282      * @param buildDirectlyFromRow indicates that we are building the clone directly
283      * from a row as opposed to building the original from the row, putting it in
284      * the shared cache, and then cloning the original.
285      */

286     public UnitOfWorkValueHolder createUnitOfWorkValueHolder(ValueHolderInterface attributeValue, Object JavaDoc original, Object JavaDoc clone, AbstractRecord row, UnitOfWorkImpl unitOfWork, boolean buildDirectlyFromRow) {
287         throw DescriptorException.invalidMappingOperation(this, "createUnitOfWorkValueHolder");
288     }
289
290     /**
291      * INTERNAL:
292      * Extract the nested attribute expressions that apply to this mapping.
293      * This is used for partial objects and joining.
294      * @param rootExpressionsAllowed true if newRoot itself can be one of the
295      * expressions returned
296      */

297     protected Vector extractNestedExpressions(List expressions, ExpressionBuilder newRoot, boolean rootExpressionsAllowed) {
298         Vector nestedExpressions = oracle.toplink.essentials.internal.helper.NonSynchronizedVector.newInstance(expressions.size());
299
300         for (Iterator expressionsEnum = expressions.iterator();
301                  expressionsEnum.hasNext();) {
302             Expression next = (Expression)expressionsEnum.next();
303
304             // The expressionBuilder can be one of the locked expressions in
305
// the ForUpdateOfClause.
306
if (!next.isQueryKeyExpression()) {
307                 continue;
308             }
309             QueryKeyExpression expression = (QueryKeyExpression)next;
310             QueryKeyExpression base = expression;
311             boolean afterBase = false;
312             while (!base.getBaseExpression().isExpressionBuilder()) {
313                 afterBase = true;
314                 base = (QueryKeyExpression)base.getBaseExpression();
315             }
316             if (afterBase && base.getName().equals(getAttributeName())) {
317                 nestedExpressions.addElement(expression.rebuildOn(base, newRoot));
318             } else if (rootExpressionsAllowed && expression.getBaseExpression().isExpressionBuilder() && expression.getName().equals(getAttributeName())) {
319                 nestedExpressions.addElement(newRoot);
320             }
321         }
322         return nestedExpressions;
323     }
324
325     /**
326      * ADVANCED:
327      * Return the attributeAccessor.
328      * The attribute accessor is responsible for setting and retrieving the attribute value
329      * from the object for this mapping.
330      */

331     public AttributeAccessor getAttributeAccessor() {
332         return attributeAccessor;
333     }
334
335     /**
336      * PUBLIC:
337      * The classification type for the attribute this mapping represents
338      */

339     public Class JavaDoc getAttributeClassification() {
340         return null;
341     }
342
343     /**
344      * PUBLIC:
345      * Return the name of the attribute set in the mapping.
346      */

347     public String JavaDoc getAttributeName() {
348         return getAttributeAccessor().getAttributeName();
349     }
350
351     /**
352      * INTERNAL:
353      * Return the value of an attribute which this mapping represents for an object.
354      */

355     public Object JavaDoc getAttributeValueFromObject(Object JavaDoc object) throws DescriptorException {
356         try {
357             return getAttributeAccessor().getAttributeValueFromObject(object);
358         } catch (DescriptorException exception) {
359             exception.setMapping(this);
360             throw exception;
361         }
362     }
363
364     /**
365      * INTERNAL:
366      * Return the mapping's containerPolicy.
367      */

368     public ContainerPolicy getContainerPolicy() {
369         throw DescriptorException.invalidMappingOperation(this, "getContainerPolicy");
370     }
371
372     /**
373      * INTERNAL:
374      * Return the descriptor to which this mapping belongs
375      */

376     public ClassDescriptor getDescriptor() {
377         return descriptor;
378     }
379
380     /**
381      * INTERNAL:
382      * Return the field associated with this mapping if there is exactly one.
383      * This is required for object relational mapping to print them, but because
384      * they are defined in Enterprise they cannot be cast to.
385      * Mappings that have a field include direct mappings and object relational mappings.
386      */

387     public DatabaseField getField() {
388         return null;
389     }
390
391     /**
392      * INTERNAL:
393      * Return the classifiction for the field contained in the mapping.
394      * This is used to convert the row value to a consistent java value.
395      * By default this is unknown.
396      */

397     public Class JavaDoc getFieldClassification(DatabaseField fieldToClassify) {
398         return null;
399     }
400
401     /**
402      * INTERNAL:
403      * Returns a vector of all the fields this mapping represents.
404      */

405     public Vector getFields() {
406         return this.fields;
407     }
408
409     /**
410      * PUBLIC:
411      * This method is invoked reflectively on the reference object to return the value of the
412      * attribute in the object. This method returns the name of the getMethodName or null if not using method access.
413      */

414     public String JavaDoc getGetMethodName() {
415         if (!(getAttributeAccessor() instanceof MethodAttributeAccessor)) {
416             return null;
417         }
418         return ((MethodAttributeAccessor)getAttributeAccessor()).getGetMethodName();
419     }
420
421     /**
422      * INTERNAL:
423      * used as a temporary store for custom SDK usage
424      */

425     public Map getProperties() {
426         if (properties == null) {//Lazy initialize to conserve space and allocation time.
427
properties = new HashMap(5);
428         }
429         return properties;
430     }
431
432     /**
433      * INTERNAL:
434      * used as a temporary store for custom SDK usage
435      */

436     public Object JavaDoc getProperty(Object JavaDoc property) {
437         if (properties == null) {
438             return null;
439         }
440
441         return getProperties().get(property);
442     }
443
444     /**
445      * INTERNAL:
446      * Return the value of an attribute unwrapping value holders if required.
447      */

448     public Object JavaDoc getRealAttributeValueFromObject(Object JavaDoc object, AbstractSession session) throws DescriptorException {
449         return getAttributeValueFromObject(object);
450     }
451
452     /**
453      * INTERNAL:
454      * Return the value of an attribute, unwrapping value holders if necessary.
455      * If the value is null, build a new container.
456      */

457     public Object JavaDoc getRealCollectionAttributeValueFromObject(Object JavaDoc object, AbstractSession session) throws DescriptorException {
458         throw DescriptorException.invalidMappingOperation(this, "getRealCollectionAttributeValueFromObject");
459     }
460
461     /**
462      * INTERNAL:
463      * Return the referenceDescriptor. This is a descriptor which is associated with
464      * the reference class.
465      * Replaced by {@link #getReferenceClassDescriptor()}
466      */

467     public ClassDescriptor getReferenceDescriptor() {
468         return null;
469     }
470
471     /**
472      * PUBLIC:
473      * Return the referenceDescriptor. This is a descriptor which is associated with
474      * the reference class.
475      */

476     public ClassDescriptor getReferenceClassDescriptor() {
477         ClassDescriptor desc = getReferenceDescriptor();
478         if (desc instanceof ClassDescriptor) {
479             return (ClassDescriptor)desc;
480         } else {
481             throw ValidationException.cannotCastToClass(desc, desc.getClass(), ClassDescriptor.class);
482         }
483     }
484
485     /**
486      * INTERNAL:
487      * Return the relationshipPartner mapping for this bi-directional mapping. If the relationshipPartner is null then
488      * this is a uni-directional mapping.
489      */

490     public DatabaseMapping getRelationshipPartner() {
491         return null;
492     }
493
494     /**
495      * PUBLIC:
496      * This method is invoked reflectively on the reference object to set the value of the
497      * attribute in the object. This method returns the name of the setMethodName or null if not using method access.
498      */

499     public String JavaDoc getSetMethodName() {
500         if (!(getAttributeAccessor() instanceof MethodAttributeAccessor)) {
501             return null;
502         }
503         return ((MethodAttributeAccessor)getAttributeAccessor()).getSetMethodName();
504     }
505
506     /**
507      * INTERNAL:
508      * Return the weight of the mapping, used to sort mappings to ensure that
509      * DirectToField Mappings get merged first
510      */

511     public Integer JavaDoc getWeight() {
512         return this.weight;
513     }
514
515     /**
516      * INTERNAL:
517      * The returns if the mapping has any constraint dependencies, such as foreign keys and join tables.
518      */

519     public boolean hasConstraintDependency() {
520         return false;
521     }
522
523     /**
524      * PUBLIC:
525      * Return if method access is used.
526      */

527     public boolean isUsingMethodAccess() {
528         return getAttributeAccessor() instanceof MethodAttributeAccessor;
529     }
530
531     /**
532      * INTERNAL:
533      * Return if the mapping has any ownership or other dependency over its target object(s).
534      */

535     public boolean hasDependency() {
536         return isPrivateOwned();
537     }
538
539     /**
540      * INTERNAL:
541      * The returns if the mapping has any inverse constraint dependencies, such as foreign keys and join tables.
542      */

543     public boolean hasInverseConstraintDependency() {
544         return false;
545     }
546
547     /**
548      * INTERNAL:
549      * Allow for initialization of properties and validation.
550      */

551     public void initialize(AbstractSession session) throws DescriptorException {
552         ;
553     }
554
555     /**
556      * INTERNAL:
557      * Related mapping should implement this method to return true.
558      */

559     public boolean isAggregateCollectionMapping() {
560         return false;
561     }
562
563     /**
564      * INTERNAL:
565      * Related mapping should implement this method to return true.
566      */

567     public boolean isAggregateMapping() {
568         return false;
569     }
570
571     /**
572      * INTERNAL:
573      * Related mapping should implement this method to return true.
574      */

575     public boolean isAggregateObjectMapping() {
576         return false;
577     }
578
579     /**
580      * INTERNAL:
581      * Related mapping should implement this method to return true.
582      */

583     public boolean isCollectionMapping() {
584         return false;
585     }
586
587     /**
588      * INTERNAL:
589      */

590     public boolean isDatabaseMapping() {
591         return true;
592     }
593
594     /**
595      * INTERNAL:
596      * Related mapping should implement this method to return true.
597      */

598     public boolean isDirectCollectionMapping() {
599         return false;
600     }
601
602     /**
603      * INTERNAL:
604      * Related mapping should implement this method to return true.
605      */

606     public boolean isDirectMapMapping() {
607         return false;
608     }
609
610     /**
611      * INTERNAL:
612      * Related mapping should implement this method to return true.
613      */

614     public boolean isDirectToFieldMapping() {
615         return false;
616     }
617
618     /**
619      * INTERNAL:
620      * Related mapping should implement this method to return true.
621      */

622     public boolean isForeignReferenceMapping() {
623         return false;
624     }
625
626     /**
627      * INTERNAL:
628      * Related mapping should implement this method to return true.
629      */

630     public boolean isManyToManyMapping() {
631         return false;
632     }
633
634     /**
635      * INTERNAL:
636      * Related mapping should implement this method to return true.
637      */

638     public boolean isNestedTableMapping() {
639         return false;
640     }
641
642     /**
643      * INTERNAL:
644      * Related mapping should implement this method to return true.
645      */

646     public boolean isObjectReferenceMapping() {
647         return false;
648     }
649
650     /**
651      * INTERNAL:
652      * Related mapping should implement this method to return true.
653      */

654     public boolean isObjectTypeMapping() {
655         return false;
656     }
657
658     /**
659      * INTERNAL:
660      * Related mapping should implement this method to return true.
661      */

662     public boolean isOneToManyMapping() {
663         return false;
664     }
665
666     /**
667      * INTERNAL:
668      * Related mapping should implement this method to return true.
669      */

670     public boolean isOneToOneMapping() {
671         return false;
672     }
673
674     /**
675      * INTERNAL:
676      * Return whether the value of this mapping is optional (that is, can be
677      * null). This is a hint and is used when generating DDL. It should be
678      * disregarded for primitive types.
679      */

680     public boolean isOptional() {
681         return isOptional;
682     }
683     
684     /**
685      * INTERNAL:
686      * All EIS mappings should implement this method to return true.
687      */

688     public boolean isEISMapping() {
689         return false;
690     }
691
692     /**
693      * INTERNAL:
694      * All relational mappings should implement this method to return true.
695      */

696     public boolean isRelationalMapping() {
697         return false;
698     }
699
700     /**
701      * INTERNAL:
702      * All relational mappings should implement this method to return true.
703      */

704     public boolean isXMLMapping() {
705         return false;
706     }
707
708     /**
709      * INTERNAL:
710      * Related mapping should implement this method to return true.
711      */

712     public boolean isAbstractDirectMapping() {
713         return false;
714     }
715
716     /**
717      * INTERNAL:
718      * Related mapping should implement this method to return true.
719      */

720     public boolean isAbstractCompositeDirectCollectionMapping() {
721         return false;
722     }
723
724     /**
725      * INTERNAL:
726      * Related mapping should implement this method to return true.
727      */

728     public boolean isAbstractCompositeObjectMapping() {
729         return false;
730     }
731
732     /**
733      * INTERNAL:
734      * Related mapping should implement this method to return true.
735      */

736     public boolean isAbstractCompositeCollectionMapping() {
737         return false;
738     }
739     /**
740      * INTERNAL:
741      * Return if this mapping support joining.
742      */

743     public boolean isJoiningSupported() {
744         return false;
745     }
746     
747     /**
748      * INTERNAL:
749      * Return if this mapping requires its attribute value to be cloned.
750      */

751     public boolean isCloningRequired() {
752         return true;
753     }
754
755     /**
756      * INTERNAL:
757      * Set by the Object builder during initialization returns true if this mapping
758      * is used as a primary key mapping.
759      */

760     public boolean isPrimaryKeyMapping() {
761         return this.primaryKeyMapping;
762     }
763     /**
764      * INTERNAL:
765      * Used when determining if a mapping supports cascaded version optimistic
766      * locking.
767      */

768     public boolean isCascadedLockingSupported() {
769         return false;
770     }
771     
772     /**
773      * INTERNAL:
774      * Return if this mapping supports change tracking.
775      */

776     public boolean isChangeTrackingSupported() {
777         return false;
778     }
779     /**
780      * INTERNAL:
781      * Return if the mapping has ownership over its target object(s).
782      */

783     public boolean isPrivateOwned() {
784         return false;
785     }
786
787     /**
788      * INTERNAL:
789      * Returns true if mapping is read only else false.
790      */

791     public boolean isReadOnly() {
792         return isReadOnly;
793     }
794
795     /**
796      * INTERNAL:
797      * Related mapping should implement this method to return true.
798      */

799     public boolean isReferenceMapping() {
800         return false;
801     }
802
803     protected boolean isRemotelyInitialized() {
804         return isRemotelyInitialized;
805     }
806
807     /**
808      * INTERNAL:
809      * Related mapping should implement this method to return true.
810      */

811     public boolean isSerializedObjectMapping() {
812         return false;
813     }
814
815     /**
816      * INTERNAL:
817      * Related mapping should implement this method to return true.
818      */

819     public boolean isStructureMapping() {
820         return false;
821     }
822
823     /**
824      * INTERNAL:
825      * Related mapping should implement this method to return true.
826      */

827     public boolean isTransformationMapping() {
828         return false;
829     }
830
831     /**
832      * INTERNAL:
833      * Related mapping should implement this method to return true.
834      */

835     public boolean isTypeConversionMapping() {
836         return false;
837     }
838
839     /**
840      * INTERNAL:
841      * Related mapping should implement this method to return true.
842      */

843     public boolean isVariableOneToOneMapping() {
844         return false;
845     }
846
847     /**
848      * INTERNAL:
849      * Related mapping should implement this method to return true.
850      */

851     public boolean isDirectToXMLTypeMapping() {
852         return false;
853     }
854
855     /**
856      * INTERNAL:
857      * Some mappings support no attribute (transformation).
858      */

859     public boolean isWriteOnly() {
860         return false;
861     }
862
863     /**
864      * INTERNAL:
865      * Iterate on the appropriate attribute value.
866      */

867     public abstract void iterate(DescriptorIterator iterator);
868
869     /**
870      * INTERNAL:
871      * Iterate on the attribute value.
872      * The value holder has already been processed.
873      */

874     public void iterateOnRealAttributeValue(DescriptorIterator iterator, Object JavaDoc realAttributeValue) {
875         throw DescriptorException.invalidMappingOperation(this, "iterateOnRealAttributeValue");
876     }
877
878     /**
879      * INTERNAL:
880      * Merge changes from the source to the target object.
881      */

882     public abstract void mergeChangesIntoObject(Object JavaDoc target, ChangeRecord changeRecord, Object JavaDoc source, MergeManager mergeManager);
883
884     /**
885      * INTERNAL:
886      * Merge changes from the source to the target object.
887      */

888     public abstract void mergeIntoObject(Object JavaDoc target, boolean isTargetUninitialized, Object JavaDoc source, MergeManager mergeManager);
889
890     /**
891      * INTERNAL:
892      * Perform the commit event.
893      * This is used in the uow to delay data modifications.
894      */

895     public void performDataModificationEvent(Object JavaDoc[] event, AbstractSession session) throws DatabaseException, DescriptorException {
896         throw DescriptorException.invalidDataModificationEvent(this);
897     }
898
899     /**
900      * INTERNAL:
901      * A subclass should implement this method if it wants different behaviour.
902      * Recurse thru the parts to delete the reference objects after the actual object is deleted.
903      */

904     public void postDelete(DeleteObjectQuery query) throws DatabaseException {
905         return;
906     }
907
908     /**
909      * INTERNAL:
910      * Allow for initialization of properties and validation that have dependecies no the descriptor
911      * being initialized.
912      */

913     public void postInitialize(AbstractSession session) throws DescriptorException {
914         // Nothing by default.
915
}
916
917     /**
918      * INTERNAL:
919      * A subclass should implement this method if it wants different behaviour.
920      * Recurse thru the parts to insert the reference objects after the actual object is inserted.
921      */

922     public void postInsert(WriteObjectQuery query) throws DatabaseException {
923         return;
924     }
925
926     /**
927      * INTERNAL:
928      * A subclass should implement this method if it wants different behaviour.
929      * Recurse thru the parts to update the reference objects after the actual object is updated.
930      */

931     public void postUpdate(WriteObjectQuery query) throws DatabaseException {
932         return;
933     }
934
935     /**
936      * INTERNAL:
937      * A subclass should implement this method if it wants different behaviour.
938      * Recurse thru the parts to delete the reference objects before the actual object is deleted.
939      */

940     public void preDelete(DeleteObjectQuery query) throws DatabaseException {
941         return;
942     }
943
944     /**
945      * INTERNAL:
946      * Allow for initialization of properties and validation.
947      */

948     public void preInitialize(AbstractSession session) throws DescriptorException {
949         try {
950             getAttributeAccessor().initializeAttributes(getDescriptor().getJavaClass());
951         } catch (DescriptorException exception) {
952             exception.setMapping(this);
953             session.getIntegrityChecker().handleError(exception);
954         }
955     }
956
957     /**
958      * INTERNAL:
959      * A subclass should implement this method if it wants different behaviour.
960      * Recurse thru the parts to insert the reference objects before the actual object is inserted.
961      */

962     public void preInsert(WriteObjectQuery query) throws DatabaseException {
963         return;
964     }
965     
966     /**
967      * INTERNAL:
968      * A subclass that supports cascade version optimistic locking should
969      * implement this method to properly prepare the locking policy for their
970      * mapping type.
971      */

972     public void prepareCascadeLockingPolicy() {
973         return;
974     }
975
976     /**
977      * INTERNAL:
978      * A subclass should implement this method if it wants different behaviour.
979      * Recurse thru the parts to update the reference objects before the actual object is updated.
980      */

981     public void preUpdate(WriteObjectQuery query) throws DatabaseException {
982         return;
983     }
984
985     /**
986      * INTERNAL:
987      * Extract value from the row and set the attribute to this value in the object.
988      * return value as this value will have been converted to the appropriate type for
989      * the object.
990      */

991     public Object JavaDoc readFromRowIntoObject(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object JavaDoc targetObject, ObjectBuildingQuery sourceQuery) throws DatabaseException {
992         // This version can be called directly for reading a sequence number
993
// field, a write lock value, or a return row into an object, and hence
994
// the query is just a placeholder. Getting the correct execution
995
// session will generate an exception, so just pass in any session.
996
// In general call this version only if no field conversion needed.
997
return readFromRowIntoObject(databaseRow, joinManager, targetObject, sourceQuery, sourceQuery.getSession());
998     }
999
1000    /**
1001     * INTERNAL:
1002     * Extract value from the row and set the attribute to this value in the object.
1003     * return value as this value will have been converted to the appropriate type for
1004     * the object.
1005     */

1006    public Object JavaDoc readFromRowIntoObject(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object JavaDoc targetObject, ObjectBuildingQuery sourceQuery, AbstractSession executionSession) throws DatabaseException {
1007        Object JavaDoc attributeValue = valueFromRow(databaseRow, joinManager, sourceQuery, executionSession);
1008        setAttributeValueInObject(targetObject, attributeValue);
1009        return attributeValue;
1010    }
1011
1012    /**
1013     * PUBLIC:
1014     * To make mapping read only.
1015     * Read-only mappings can be used if two attributes map to the same field.
1016     * Read-only mappings cannot be used for the primary key or other required fields.
1017     */

1018    public void readOnly() {
1019        setIsReadOnly(true);
1020    }
1021
1022    /**
1023     * PUBLIC:
1024     * The mapping can be dynamically made either readOnly or readWriteOnly. This makes mapping go back to
1025     * default mode.
1026     */

1027    public void readWrite() {
1028        setIsReadOnly(false);
1029    }
1030
1031    /**
1032     * INTERNAL:
1033     * Rehash any hashtables based on fields.
1034     * This is used to clone descriptors for aggregates, which hammer field names,
1035     * it is probably better not to hammer the field name and this should be refactored.
1036     */

1037    public void rehashFieldDependancies(AbstractSession session) {
1038        // Should be overwritten by any mapping with fields.
1039
}
1040
1041    /**
1042     * ADVANCED:
1043     * Set the attributeAccessor.
1044     * The attribute accessor is responsible for setting and retrieving the attribute value
1045     * from the object for this mapping.
1046     * This can be set to an implementor of AttributeAccessor if the attribute
1047     * requires advanced conversion of the mapping value, or a real attribute does not exist.
1048     */

1049    public void setAttributeAccessor(AttributeAccessor attributeAccessor) {
1050        String JavaDoc attributeName = getAttributeName();
1051        this.attributeAccessor = attributeAccessor;
1052        if (attributeAccessor.getAttributeName() == null) {
1053            attributeAccessor.setAttributeName(attributeName);
1054        }
1055    }
1056
1057    /**
1058     * PUBLIC:
1059     * Sets the name of the attribute in the mapping.
1060     */

1061    public void setAttributeName(String JavaDoc attributeName) {
1062        getAttributeAccessor().setAttributeName(attributeName);
1063    }
1064
1065    /**
1066     * INTERNAL:
1067     * Set the value of the attribute mapped by this mapping.
1068     */

1069    public void setAttributeValueInObject(Object JavaDoc object, Object JavaDoc value) throws DescriptorException {
1070        // PERF: Direct variable access.
1071
try {
1072            this.attributeAccessor.setAttributeValueInObject(object, value);
1073        } catch (DescriptorException exception) {
1074            exception.setMapping(this);
1075            throw exception;
1076        }
1077    }
1078
1079    /**
1080     * INTERNAL:
1081     * Set the value of the attribute mapped by this mapping,
1082     * placing it inside a value holder if necessary.
1083     */

1084    public void setRealAttributeValueInObject(Object JavaDoc object, Object JavaDoc value) throws DescriptorException {
1085        try {
1086            this.setAttributeValueInObject(object, value);
1087        } catch (DescriptorException exception) {
1088            exception.setMapping(this);
1089            throw exception;
1090        }
1091    }
1092
1093    /**
1094     * INTERNAL:
1095     * Set the descriptor to which this mapping belongs
1096     */

1097    public void setDescriptor(ClassDescriptor descriptor) {
1098        this.descriptor = descriptor;
1099    }
1100
1101    /**
1102     * INTERNAL:
1103     * Set the mapping's field collection.
1104     */

1105    protected void setFields(Vector fields) {
1106        this.fields = fields;
1107    }
1108
1109    /**
1110     * PUBLIC:
1111     * This method is invoked reflectively on the reference object to return the value of the
1112     * attribute in the object. This method sets the name of the getMethodName.
1113     */

1114    public void setGetMethodName(String JavaDoc methodName) {
1115        if (methodName == null) {
1116            return;
1117        }
1118
1119        // This is done because setting attribute name by defaults create InstanceVariableAttributeAccessor
1120
if (getAttributeAccessor() instanceof InstanceVariableAttributeAccessor) {
1121            String JavaDoc attributeName = this.attributeAccessor.getAttributeName();
1122            setAttributeAccessor(new MethodAttributeAccessor());
1123            getAttributeAccessor().setAttributeName(attributeName);
1124        }
1125
1126        ((MethodAttributeAccessor)getAttributeAccessor()).setGetMethodName(methodName);
1127    }
1128
1129    /**
1130     * INTERNAL:
1131     * Used to specify whether the value of this mapping may be null. It is
1132     * used when generating DDL.
1133     */

1134    public void setIsOptional(boolean isOptional) {
1135        this.isOptional = isOptional;
1136    }
1137    
1138    /**
1139     * INTERNAL:
1140     * Set by the Object builder during initialization returns true if this mapping
1141     * is used as a primary key mapping.
1142     */

1143    public void setIsPrimaryKeyMapping(boolean pkMapping) {
1144        this.primaryKeyMapping = pkMapping;
1145    }
1146
1147    /**
1148     * PUBLIC:
1149     * Set this mapping to be read only.
1150     * Read-only mappings can be used if two attributes map to the same field.
1151     * Read-only mappings cannot be used for the primary key or other required fields.
1152     */

1153    public void setIsReadOnly(boolean aBoolean) {
1154        isReadOnly = aBoolean;
1155    }
1156
1157    /**
1158     * INTERNAL:
1159     * used as a temporary store for custom SDK usage
1160     */

1161    public void setProperties(Map properties) {
1162        this.properties = properties;
1163    }
1164
1165    /**
1166     * ADVANCED:
1167     * Allow user defined properties.
1168     */

1169    public void setProperty(Object JavaDoc property, Object JavaDoc value) {
1170        getProperties().put(property, value);
1171    }
1172
1173    /**
1174     * PUBLIC:
1175     * This method is invoked reflectively on the reference object to get the value of the attribute.
1176     * The method defined on the object should actually return the value that needs to be set in the
1177     * attribute accessor.
1178     */

1179    public void setSetMethodName(String JavaDoc methodName) {
1180        if (methodName == null) {
1181            return;
1182        }
1183
1184        // This is done because setting attribute name by defaults create InstanceVariableAttributeAccessor
1185
if (!(getAttributeAccessor() instanceof MethodAttributeAccessor)) {
1186            String JavaDoc attributeName = this.attributeAccessor.getAttributeName();
1187            setAttributeAccessor(new MethodAttributeAccessor());
1188            getAttributeAccessor().setAttributeName(attributeName);
1189        }
1190
1191        ((MethodAttributeAccessor)getAttributeAccessor()).setSetMethodName(methodName);
1192    }
1193
1194    /**
1195     * ADVANCED:
1196     * Set the weight of the mapping, used to sort mappings
1197     * DirectToField Mappings have a default weight of 1 while all other Mappings have a
1198     * default weight of MAXINT. Ordering of Mappings can be achieved by setting the weight of
1199     * a particular mapping to a value within the above mentioned limits. By ordering mappings
1200     * the user can control what order relationships are processed by TopLink.
1201     */

1202
1203    // CR 4097
1204
public void setWeight(Integer JavaDoc newWeight) {
1205        this.weight = newWeight;
1206    }
1207
1208    /**
1209     * ADVANCED:
1210     * This method is used to add an object to a collection once the changeSet is applied.
1211     * The referenceKey parameter should only be used for direct Maps.
1212     */

1213    public void simpleAddToCollectionChangeRecord(Object JavaDoc referenceKey, Object JavaDoc changeSetToAdd, ObjectChangeSet changeSet, AbstractSession session) throws DescriptorException {
1214        throw DescriptorException.invalidMappingOperation(this, "simpleAddToCollectionChangeRecord");
1215    }
1216
1217    /**
1218     * ADVANCED:
1219     * This method is used to remove an object from a collection once the changeSet is applied.
1220     * The referenceKey parameter should only be used for direct Maps.
1221     */

1222    public void simpleRemoveFromCollectionChangeRecord(Object JavaDoc referenceKey, Object JavaDoc changeSetToAdd, ObjectChangeSet changeSet, AbstractSession session) throws DescriptorException {
1223        throw DescriptorException.invalidMappingOperation(this, "simpleRemoveFromCollectionChangeRecord");
1224    }
1225
1226    /**
1227     * INTERNAL:
1228     * Print the mapping attribute name, this is used in error messages.
1229     */

1230    public String JavaDoc toString() {
1231        return getClass().getName() + "[" + getAttributeName() + "]";
1232    }
1233
1234    /**
1235     * INTERNAL:
1236     * Allow for subclasses to perform validation.
1237     */

1238    public void validateAfterInitialization(AbstractSession session) throws DescriptorException {
1239    }
1240
1241    /**
1242     * INTERNAL:
1243     * Allow for subclasses to perform validation.
1244     */

1245    public void validateBeforeInitialization(AbstractSession session) throws DescriptorException {
1246    }
1247
1248    /**
1249     * INTERNAL:
1250     * A subclass should extract the value from the object for the field, if it does not map the field then
1251     * it should return null.
1252     * Return the Value from the object.
1253     */

1254    public Object JavaDoc valueFromObject(Object JavaDoc anObject, DatabaseField field, AbstractSession session) {
1255        return null;
1256    }
1257
1258    /**
1259     * INTERNAL:
1260     * A subclass should implement this method if it wants different behaviour.
1261     * Returns the value for the mapping from the database row.
1262     */

1263    public Object JavaDoc valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query) throws DatabaseException {
1264        return valueFromRow(row, joinManager, query, query.getSession().getExecutionSession(query));
1265    }
1266
1267    /**
1268     * INTERNAL:
1269     *
1270     */

1271    public Object JavaDoc valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query, AbstractSession session) throws DatabaseException {
1272        return null;
1273    }
1274
1275    /**
1276     * INTERNAL:
1277     * To verify if the specified object has been deleted or not.
1278     */

1279    public boolean verifyDelete(Object JavaDoc object, AbstractSession session) throws DatabaseException {
1280        return true;
1281    }
1282
1283    /**
1284     * INTERNAL:
1285     * A subclass should implement this method if it wants different behaviour.
1286     * Write the foreign key values from the attribute to the row.
1287     */

1288     
1289    public void writeFromAttributeIntoRow(Object JavaDoc attribute, AbstractRecord row, AbstractSession session)
1290    {
1291        // Do nothing by default.
1292
}
1293    /**
1294     * INTERNAL:
1295     * A subclass should implement this method if it wants different behaviour.
1296     * Write the attribute value from the object to the row.
1297     */

1298    public void writeFromObjectIntoRow(Object JavaDoc object, AbstractRecord row, AbstractSession session) {
1299        // Do nothing by default.
1300
}
1301
1302    /**
1303     * INTERNAL:
1304     * This row is built for shallow insert which happens in case of bidirectional inserts.
1305     */

1306    public void writeFromObjectIntoRowForShallowInsert(Object JavaDoc object, AbstractRecord row, AbstractSession session) {
1307        writeFromObjectIntoRow(object, row, session);
1308    }
1309
1310    /**
1311     * INTERNAL:
1312     * A subclass should implement this method if it wants different behaviour.
1313     * Write the attribute value from the object to the row.
1314     */

1315    public void writeFromObjectIntoRowWithChangeRecord(ChangeRecord changeRecord, AbstractRecord row, AbstractSession session) {
1316        // Do nothing by default.
1317
}
1318
1319    /**
1320     * INTERNAL:
1321     * This row is built for shallow insert which happens in case of bidirectional inserts.
1322     */

1323    public void writeFromObjectIntoRowForShallowInsertWithChangeRecord(ChangeRecord changeRecord, AbstractRecord row, AbstractSession session) {
1324        writeFromObjectIntoRowWithChangeRecord(changeRecord, row, session);
1325    }
1326
1327    /**
1328     * INTERNAL:
1329     * Write the attribute value from the object to the row for update.
1330     */

1331    public void writeFromObjectIntoRowForUpdate(WriteObjectQuery query, AbstractRecord row) {
1332        writeFromObjectIntoRow(query.getObject(), row, query.getSession());
1333    }
1334
1335    /**
1336     * INTERNAL:
1337     * A subclass should implement this method if it wants different behaviour.
1338     * Write the attribute value from the object to the row.
1339     */

1340    public void writeFromObjectIntoRowForWhereClause(ObjectLevelModifyQuery query, AbstractRecord row) {
1341        Object JavaDoc object;
1342        if (query.isDeleteObjectQuery()) {
1343            object = query.getObject();
1344        } else {
1345            object = query.getBackupClone();
1346        }
1347        writeFromObjectIntoRow(object, row, query.getSession());
1348    }
1349
1350    /**
1351     * INTERNAL:
1352     * Write fields needed for insert into the template for with null values.
1353     */

1354    public void writeInsertFieldsIntoRow(AbstractRecord databaseRow, AbstractSession session) {
1355        // Do nothing by default.
1356
}
1357
1358    /**
1359     * INTERNAL:
1360     * Write fields needed for update into the template for with null values.
1361     * By default inserted fields are used.
1362     */

1363    public void writeUpdateFieldsIntoRow(AbstractRecord databaseRow, AbstractSession session) {
1364        writeInsertFieldsIntoRow(databaseRow, session);
1365    }
1366
1367    /**
1368     * INTERNAL:
1369     * Either create a new change record or update the change record with the new value.
1370     * This is used by attribute change tracking.
1371     */

1372    public void updateChangeRecord(Object JavaDoc clone, Object JavaDoc newValue, Object JavaDoc oldValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException {
1373        throw DescriptorException.invalidMappingOperation(this, "updateChangeRecord");
1374    }
1375
1376    /**
1377     * INTERNAL:
1378     * Add a new value and its change set to the collection change record. This is used by
1379     * attribute change tracking.
1380     */

1381    public void addToCollectionChangeRecord(Object JavaDoc newKey, Object JavaDoc newValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException {
1382        throw DescriptorException.invalidMappingOperation(this, "addToCollectionChangeRecord");
1383    }
1384
1385    /**
1386     * INTERNAL:
1387     * Remove a value and its change set from the collection change record. This is used by
1388     * attribute change tracking.
1389     */

1390    public void removeFromCollectionChangeRecord(Object JavaDoc newKey, Object JavaDoc newValue, ObjectChangeSet objectChangeSet, UnitOfWorkImpl uow) throws DescriptorException {
1391        throw DescriptorException.invalidMappingOperation(this, "removeFromCollectionChangeRecord");
1392    }
1393
1394    /**
1395     * INTERNAL:
1396     * Directly build a change record without comparison
1397     */

1398    public ChangeRecord buildChangeRecord(Object JavaDoc newValue, ObjectChangeSet owner, AbstractSession session) throws DescriptorException {
1399        throw DescriptorException.invalidMappingOperation(this, "buildChangeRecord");
1400    }
1401}
1402
Popular Tags