KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > access > DataNodeSyncQualifierDescriptor


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.access;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import org.apache.commons.collections.Transformer;
29 import org.apache.cayenne.CayenneRuntimeException;
30 import org.apache.cayenne.ObjectId;
31 import org.apache.cayenne.map.DbAttribute;
32 import org.apache.cayenne.map.DbEntity;
33 import org.apache.cayenne.map.DbJoin;
34 import org.apache.cayenne.map.DbRelationship;
35 import org.apache.cayenne.map.ObjAttribute;
36 import org.apache.cayenne.map.ObjEntity;
37 import org.apache.cayenne.map.ObjRelationship;
38
39 /**
40  * Builds update qualifier snapshots, including optimistic locking.
41  *
42  * @since 1.2
43  * @author Andrus Adamchik
44  */

45 class DataNodeSyncQualifierDescriptor {
46
47     private List JavaDoc attributes;
48     private List JavaDoc valueTransformers;
49     private boolean usingOptimisticLocking;
50
51     public boolean isUsingOptimisticLocking() {
52         return usingOptimisticLocking;
53     }
54
55     List JavaDoc getAttributes() {
56         return attributes;
57     }
58
59     Map JavaDoc createQualifierSnapshot(ObjectDiff diff) {
60         int len = attributes.size();
61
62         Map JavaDoc map = new HashMap JavaDoc(len * 2);
63         for (int i = 0; i < len; i++) {
64             DbAttribute attribute = (DbAttribute) attributes.get(i);
65             if (!map.containsKey(attribute.getName())) {
66
67                 Object JavaDoc value = ((Transformer) valueTransformers.get(i)).transform(diff);
68                 map.put(attribute.getName(), value);
69             }
70         }
71
72         return map;
73     }
74
75     void reset(ObjEntity entity, DbEntity dbEntity) {
76         attributes = new ArrayList JavaDoc(3);
77         valueTransformers = new ArrayList JavaDoc(3);
78         usingOptimisticLocking = entity.getLockType() == ObjEntity.LOCK_TYPE_OPTIMISTIC;
79
80         // master PK columns
81
if (entity.getDbEntity() == dbEntity) {
82             Iterator JavaDoc pkIt = entity.getDbEntity().getPrimaryKey().iterator();
83             while (pkIt.hasNext()) {
84                 final DbAttribute attribute = (DbAttribute) pkIt.next();
85                 attributes.add(attribute);
86                 valueTransformers.add(new Transformer() {
87
88                     public Object JavaDoc transform(Object JavaDoc input) {
89                         ObjectId id = (ObjectId) ((ObjectDiff) input).getNodeId();
90                         return id.getIdSnapshot().get(attribute.getName());
91                     }
92                 });
93             }
94         }
95         else {
96             // detail table PK columns
97
DbRelationship masterDependentDbRel = findMasterToDependentDbRelationship(
98                     entity.getDbEntity(),
99                     dbEntity);
100
101             if (masterDependentDbRel != null) {
102
103                 Iterator JavaDoc joinsIterator = masterDependentDbRel.getJoins().iterator();
104                 while (joinsIterator.hasNext()) {
105                     final DbJoin dbAttrPair = (DbJoin) joinsIterator.next();
106                     DbAttribute dbAttribute = dbAttrPair.getTarget();
107                     if (!attributes.contains(dbAttribute)) {
108
109                         attributes.add(dbAttribute);
110                         valueTransformers.add(new Transformer() {
111
112                             public Object JavaDoc transform(Object JavaDoc input) {
113                                 ObjectId id = (ObjectId) ((ObjectDiff) input).getNodeId();
114                                 return id.getIdSnapshot().get(dbAttrPair.getSourceName());
115                             }
116                         });
117                     }
118                 }
119             }
120         }
121
122         if (usingOptimisticLocking) {
123
124             Iterator JavaDoc attributeIt = entity.getAttributes().iterator();
125             while (attributeIt.hasNext()) {
126                 final ObjAttribute attribute = (ObjAttribute) attributeIt.next();
127
128                 if (attribute.isUsedForLocking()) {
129                     // only care about first step in a flattened attribute
130
DbAttribute dbAttribute = (DbAttribute) attribute
131                             .getDbPathIterator()
132                             .next();
133
134                     if (!attributes.contains(dbAttribute)) {
135                         attributes.add(dbAttribute);
136
137                         valueTransformers.add(new Transformer() {
138
139                             public Object JavaDoc transform(Object JavaDoc input) {
140                                 return ((ObjectDiff) input).getSnapshotValue(attribute
141                                         .getName());
142                             }
143                         });
144                     }
145                 }
146             }
147
148             Iterator JavaDoc relationshipIt = entity.getRelationships().iterator();
149             while (relationshipIt.hasNext()) {
150                 final ObjRelationship relationship = (ObjRelationship) relationshipIt
151                         .next();
152
153                 if (relationship.isUsedForLocking()) {
154                     // only care about the first DbRelationship
155
DbRelationship dbRelationship = (DbRelationship) relationship
156                             .getDbRelationships()
157                             .get(0);
158
159                     Iterator JavaDoc joinsIterator = dbRelationship.getJoins().iterator();
160                     while (joinsIterator.hasNext()) {
161                         final DbJoin dbAttrPair = (DbJoin) joinsIterator.next();
162                         DbAttribute dbAttribute = dbAttrPair.getSource();
163
164                         // relationship transformers override attribute transformers for
165
// meaningful FK's... why meanigful FKs can go out of sync is
166
// another story (CAY-595)
167
int index = attributes.indexOf(dbAttribute);
168                         if (index >= 0 && !dbAttribute.isForeignKey()) {
169                             continue;
170                         }
171
172                         Object JavaDoc transformer = new Transformer() {
173
174                             public Object JavaDoc transform(Object JavaDoc input) {
175                                 ObjectId targetId = ((ObjectDiff) input)
176                                         .getArcSnapshotValue(relationship.getName());
177                                 return targetId != null ? targetId.getIdSnapshot().get(
178                                         dbAttrPair.getTargetName()) : null;
179                             }
180                         };
181
182                         if (index < 0) {
183                             attributes.add(dbAttribute);
184                             valueTransformers.add(transformer);
185                         }
186                         else {
187                             valueTransformers.set(index, transformer);
188                         }
189                     }
190                 }
191             }
192         }
193     }
194
195     private DbRelationship findMasterToDependentDbRelationship(
196             DbEntity masterDbEntity,
197             DbEntity dependentDbEntity) {
198
199         Iterator JavaDoc it = masterDbEntity.getRelationshipMap().values().iterator();
200         while (it.hasNext()) {
201
202             DbRelationship relationship = (DbRelationship) it.next();
203             if (dependentDbEntity.equals(relationship.getTargetEntity())
204                     && relationship.isToDependentPK()) {
205
206                 if (relationship.isToMany()) {
207                     throw new CayenneRuntimeException(
208                             "Only 'to one' master-detail relationships can be processed.");
209                 }
210
211                 return relationship;
212             }
213         }
214
215         return null;
216     }
217 }
218
Popular Tags