KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > indirection > UnitOfWorkQueryValueHolder


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, 2005, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.indirection;
23
24 import oracle.toplink.essentials.indirection.*;
25 import oracle.toplink.essentials.internal.helper.ClassConstants;
26 import oracle.toplink.essentials.mappings.*;
27 import oracle.toplink.essentials.internal.sessions.AbstractRecord;
28 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl;
29 import oracle.toplink.essentials.descriptors.ClassDescriptor;
30
31 /**
32  * UnitOfWorkQueryValueHolder wraps a database-stored object and
33  * implements behavior to access it. The object is read from
34  * the database by invoking a user-specified query.
35  * This value holder is used only in the unit of work.
36  *
37  * @author Sati
38  */

39 public class UnitOfWorkQueryValueHolder extends UnitOfWorkValueHolder {
40     protected UnitOfWorkQueryValueHolder(ValueHolderInterface attributeValue, Object JavaDoc clone, DatabaseMapping mapping, UnitOfWorkImpl unitOfWork) {
41         super(attributeValue, clone, mapping, unitOfWork);
42     }
43
44     public UnitOfWorkQueryValueHolder(ValueHolderInterface attributeValue, Object JavaDoc clone, ForeignReferenceMapping mapping, AbstractRecord row, UnitOfWorkImpl unitOfWork) {
45         this(attributeValue, clone, mapping, unitOfWork);
46         this.row = row;
47     }
48
49     /**
50      * Backup the clone attribute value.
51      */

52     protected Object JavaDoc buildBackupCloneFor(Object JavaDoc cloneAttributeValue) {
53         return getMapping().buildBackupCloneForPartObject(cloneAttributeValue, null, null, getUnitOfWork());
54     }
55
56     /**
57      * Clone the original attribute value.
58      */

59     public Object JavaDoc buildCloneFor(Object JavaDoc originalAttributeValue) {
60         return getMapping().buildCloneForPartObject(originalAttributeValue, null, this.relationshipSourceObject, getUnitOfWork(), true);
61     }
62
63     /**
64      * Ensure that the backup value holder is populated.
65      */

66     public void setValue(Object JavaDoc theValue) {
67         // Must force instantiation to be able to compare with the old value.
68
if (!isInstantiated()) {
69             instantiate();
70         }
71         Object JavaDoc oldValue = getValue();
72         super.setValue(theValue);
73         updateForeignReferenceSet(theValue, oldValue);
74     }
75
76     /**
77      * INTERNAL:
78      * Here we now must check for bi-directional relationship.
79      * If the mapping has a relationship partner then we must maintain the original relationship.
80      * We only worry about ObjectReferenceMappings as the collections mappings will be handled by transparentIndirection
81      */

82     public void updateForeignReferenceRemove(Object JavaDoc value) {
83         DatabaseMapping sourceMapping = this.getMapping();
84         if (sourceMapping == null) {
85             //mapping is a transient attribute. If it does not exist then we have been serialized
86
return;
87         }
88
89         if (sourceMapping.isPrivateOwned()) {
90             // don't null out backpointer on private owned relationship because it will cause an
91
// extra update.
92
return;
93         }
94
95         // ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
96
ForeignReferenceMapping partner = this.getRelationshipPartnerFor(value);
97         if (partner != null) {
98             if (value != null) {
99                 Object JavaDoc unwrappedValue = partner.getDescriptor().getObjectBuilder().unwrapObject(value, getSession());
100                 Object JavaDoc oldParent = partner.getRealAttributeValueFromObject(unwrappedValue, getSession());
101                 Object JavaDoc sourceObject = getRelationshipSourceObject();
102                 
103                 if ((oldParent == null) || (partner.isCollectionMapping() && !(partner.getContainerPolicy().contains(sourceObject, oldParent, getSession())))) {
104                     // value has already been set
105
return;
106                 }
107
108                 if (partner.isObjectReferenceMapping()) {
109                     // Check if it's already been set to null
110
partner.setRealAttributeValueInObject(unwrappedValue, null);
111                 } else if (partner.isCollectionMapping()) {
112                     // If it is not in the collection then it has already been removed.
113
partner.getContainerPolicy().removeFrom(sourceObject, oldParent, getSession());
114                 }
115             }
116         }
117     }
118
119     /**
120      * INTERNAL:
121      * Here we now must check for bi-directional relationship.
122      * If the mapping has a relationship partner then we must maintain the original relationship.
123      * We only worry about ObjectReferenceMappings as the collections mappings will be handled by transparentIndirection
124      */

125     public void updateForeignReferenceSet(Object JavaDoc value, Object JavaDoc oldValue) {
126         if ((value != null) && (ClassConstants.Collection_Class.isAssignableFrom(value.getClass()))) {
127             //I'm passing a collection into the valueholder not an object
128
return;
129         }
130         if (getMapping() == null) {
131             //mapping is a transient attribute. If it does not exist then we have been serialized
132
return;
133         }
134
135         // ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
136
ForeignReferenceMapping partner = this.getRelationshipPartnerFor(value);
137         if (partner != null) {
138             if (value != null) {
139                 Object JavaDoc unwrappedValue = partner.getDescriptor().getObjectBuilder().unwrapObject(value, getSession());
140                 Object JavaDoc oldParent = partner.getRealAttributeValueFromObject(unwrappedValue, getSession());
141                 Object JavaDoc sourceObject = getRelationshipSourceObject();
142                 Object JavaDoc wrappedSource = getMapping().getDescriptor().getObjectBuilder().wrapObject(sourceObject, getSession());
143                 
144                 if ((oldParent == sourceObject) || (partner.isCollectionMapping() && partner.getContainerPolicy().contains(sourceObject, oldParent, getSession()))) {
145                     // value has already been set
146
return;
147                 }
148
149                 // Set the Object that was refereceing this value to reference null, or remove value from its collection
150
if (oldParent != null) {
151                     if (getMapping().isObjectReferenceMapping()) {
152                         if (!partner.isCollectionMapping()) {
153                             // If the back pointer is a collection it's OK that I'm adding myself into the collection
154
((ObjectReferenceMapping)getMapping()).setRealAttributeValueInObject(oldParent, null);
155                         }
156                     } else if (getMapping().isCollectionMapping() && (!partner.isManyToManyMapping())) {
157                         getMapping().getContainerPolicy().removeFrom(unwrappedValue, getMapping().getRealAttributeValueFromObject(oldParent, getSession()), getSession());
158                     }
159                 }
160                 
161                 if (oldValue != null) {
162                     // CR 3487
163
Object JavaDoc unwrappedOldValue = partner.getDescriptor().getObjectBuilder().unwrapObject(oldValue, getSession());
164
165                     // if this object was referencing a different object reset the back pointer on that object
166
if (partner.isObjectReferenceMapping()) {
167                         partner.setRealAttributeValueInObject(unwrappedOldValue, null);
168                     } else if (partner.isCollectionMapping()) {
169                         partner.getContainerPolicy().removeFrom(sourceObject, partner.getRealAttributeValueFromObject(unwrappedOldValue, getSession()), getSession());
170                     }
171                 }
172
173                 // Now set the back reference of the value being passed in to point to this object
174
if (partner.isObjectReferenceMapping()) {
175                     partner.setRealAttributeValueInObject(unwrappedValue, wrappedSource);
176                 } else if (partner.isCollectionMapping()) {
177                     partner.getContainerPolicy().addInto(wrappedSource, oldParent, getSession());
178                 }
179             } else {
180                 updateForeignReferenceRemove(oldValue);
181             }
182         }
183     }
184
185     /**
186      * Helper method to retrieve the relationship partner mapping. This will take inheritance
187      * into account and return the mapping associated with correct subclass if necessary. This
188      * is needed for EJB 2.0 inheritance
189      */

190     private ForeignReferenceMapping getRelationshipPartnerFor(Object JavaDoc partnerObject) {
191         ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
192         if ((partner == null) || (partnerObject == null)) {
193             // no partner, nothing to do
194
return partner;
195         }
196
197         // if the target object is not an instance of the class type associated with the partner
198
// mapping, try and look up the same partner mapping but as part of the partnerObject's
199
// descriptor. Only check if inheritance is involved...
200
if (partner.getDescriptor().hasInheritance()) {
201             ClassDescriptor partnerObjectDescriptor = this.getSession().getDescriptor(partnerObject);
202             if (!(partner.getDescriptor().getJavaClass().isAssignableFrom(partnerObjectDescriptor.getJavaClass()))) {
203                 return (ForeignReferenceMapping)partnerObjectDescriptor.getMappingForAttributeName(partner.getAttributeName());
204             }
205         }
206         return partner;
207     }
208 }
209
Popular Tags