KickJava   Java API By Example, From Geeks To Geeks.

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


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.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import org.apache.cayenne.CayenneRuntimeException;
28 import org.apache.cayenne.ObjectId;
29 import org.apache.cayenne.Persistent;
30 import org.apache.cayenne.dba.PkGenerator;
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.EntitySorter;
36 import org.apache.cayenne.map.ObjAttribute;
37 import org.apache.cayenne.map.ObjEntity;
38 import org.apache.cayenne.query.InsertBatchQuery;
39 import org.apache.cayenne.reflect.ClassDescriptor;
40
41 /**
42  * @since 1.2
43  * @author Andrus Adamchik
44  */

45 class DataDomainInsertBucket extends DataDomainSyncBucket {
46
47     DataDomainInsertBucket(DataDomainFlushAction parent) {
48         super(parent);
49     }
50
51     void appendQueriesInternal(Collection JavaDoc queries) {
52
53         DataDomainDBDiffBuilder diffBuilder = new DataDomainDBDiffBuilder();
54
55         EntitySorter sorter = parent.getDomain().getEntitySorter();
56         sorter.sortDbEntities(dbEntities, false);
57
58         Iterator JavaDoc i = dbEntities.iterator();
59         while (i.hasNext()) {
60             DbEntity dbEntity = (DbEntity) i.next();
61             List JavaDoc objEntitiesForDbEntity = (List JavaDoc) descriptorsByDbEntity.get(dbEntity);
62
63             InsertBatchQuery batch = new InsertBatchQuery(dbEntity, 27);
64
65             Iterator JavaDoc j = objEntitiesForDbEntity.iterator();
66             while (j.hasNext()) {
67                 ClassDescriptor descriptor = (ClassDescriptor) j.next();
68
69                 diffBuilder.reset(descriptor.getEntity(), dbEntity);
70
71                 boolean isMasterDbEntity = (descriptor.getEntity().getDbEntity() == dbEntity);
72
73                 // remove object set for dependent entity, so that it does not show up
74
// on post processing
75
List JavaDoc objects = (List JavaDoc) (isMasterDbEntity ? objectsByDescriptor
76                         .get(descriptor) : objectsByDescriptor.remove(descriptor));
77
78                 if (objects.isEmpty()) {
79                     continue;
80                 }
81
82                 checkReadOnly(descriptor.getEntity());
83
84                 if (isMasterDbEntity) {
85                     createPermIdsForObjEntity(descriptor, objects);
86                     sorter.sortObjectsForEntity(descriptor.getEntity(), objects, false);
87                 }
88
89                 for (Iterator JavaDoc k = objects.iterator(); k.hasNext();) {
90                     Persistent o = (Persistent) k.next();
91
92                     Map JavaDoc snapshot = diffBuilder.buildDBDiff(parent.objectDiff(o
93                             .getObjectId()));
94
95                     batch.add(snapshot, o.getObjectId());
96                 }
97             }
98
99             queries.add(batch);
100         }
101     }
102
103     void createPermIdsForObjEntity(ClassDescriptor descriptor, List JavaDoc dataObjects) {
104
105         if (dataObjects.isEmpty()) {
106             return;
107         }
108
109         ObjEntity objEntity = descriptor.getEntity();
110         DbEntity dbEntity = objEntity.getDbEntity();
111         DataNode node = parent.getDomain().lookupDataNode(dbEntity.getDataMap());
112         boolean supportsGeneratedKeys = node.getAdapter().supportsGeneratedKeys();
113         
114         PkGenerator pkGenerator = node.getAdapter().getPkGenerator();
115
116         Iterator JavaDoc i = dataObjects.iterator();
117         while (i.hasNext()) {
118
119             Persistent object = (Persistent) i.next();
120             ObjectId id = object.getObjectId();
121             if (id == null || !id.isTemporary()) {
122                 continue;
123             }
124
125             // modify replacement id directly...
126
Map JavaDoc idMap = id.getReplacementIdMap();
127
128             boolean autoPkDone = false;
129             Iterator JavaDoc it = dbEntity.getPrimaryKey().iterator();
130             while (it.hasNext()) {
131                 DbAttribute dbAttr = (DbAttribute) it.next();
132                 String JavaDoc dbAttrName = dbAttr.getName();
133
134                 if (idMap.containsKey(dbAttrName)) {
135                     continue;
136                 }
137
138                 // handle meaningful PK
139
ObjAttribute objAttr = objEntity.getAttributeForDbAttribute(dbAttr);
140                 if (objAttr != null) {
141
142                     Object JavaDoc value = descriptor
143                             .getProperty(objAttr.getName())
144                             .readPropertyDirectly(object);
145
146                     if (value != null) {
147                         // treat numeric zero values as nulls requiring generation
148
if (!(value instanceof Number JavaDoc && ((Number JavaDoc) value).intValue() == 0)) {
149                             idMap.put(dbAttrName, value);
150                             continue;
151                         }
152                     }
153                 }
154                 
155                 // skip db-generated
156
if (supportsGeneratedKeys && dbAttr.isGenerated()) {
157                     continue;
158                 }
159
160                 // skip propagated
161
if (isPropagated(dbAttr)) {
162                     continue;
163                 }
164                 
165                 // only a single key can be generated from DB... if this is done already
166
// in this loop, we must bail out.
167
if (autoPkDone) {
168                     throw new CayenneRuntimeException(
169                             "Primary Key autogeneration only works for a single attribute.");
170                 }
171
172                 // finally, use database generation mechanism
173
try {
174                     Object JavaDoc pkValue = pkGenerator.generatePkForDbEntity(node, dbEntity);
175                     idMap.put(dbAttrName, pkValue);
176                     autoPkDone = true;
177                 }
178                 catch (Exception JavaDoc ex) {
179                     throw new CayenneRuntimeException("Error generating PK: "
180                             + ex.getMessage(), ex);
181                 }
182             }
183         }
184     }
185
186     // TODO, andrus 4/12/2006 - move to DbAttribute in 2.0+
187
boolean isPropagated(DbAttribute attribute) {
188         Iterator JavaDoc it = attribute.getEntity().getRelationships().iterator();
189         while (it.hasNext()) {
190
191             DbRelationship dbRel = (DbRelationship) it.next();
192             if (!dbRel.isToMasterPK()) {
193                 continue;
194             }
195
196             Iterator JavaDoc joins = dbRel.getJoins().iterator();
197             while (joins.hasNext()) {
198                 DbJoin join = (DbJoin) joins.next();
199                 if (attribute.getName().equals(join.getSourceName())) {
200                     return true;
201                 }
202             }
203         }
204
205         return false;
206     }
207 }
208
Popular Tags