KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > DataRow


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;
21
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import org.apache.commons.lang.builder.ToStringBuilder;
28 import org.apache.cayenne.map.DbAttribute;
29 import org.apache.cayenne.map.DbEntity;
30 import org.apache.cayenne.map.DbRelationship;
31 import org.apache.cayenne.map.ObjEntity;
32 import org.apache.cayenne.util.Util;
33
34 /**
35  * DataRow a map that holds values retrieved from the database for a given query row.
36  * DataRows are used to cache raw database data and as a reference point for tracking
37  * DataObject changes.
38  *
39  * @author Andrus Adamchik
40  * @since 1.1
41  */

42 public class DataRow extends HashMap JavaDoc {
43
44     // "volatile" is supposed to ensure consistency in read and increment operations;
45
// is this universally true?
46

47     // make sure the starting value is different from DataObject default version value
48
private static volatile long currentVersion = DataObject.DEFAULT_VERSION + 1;
49
50     protected long version = currentVersion++;
51     protected long replacesVersion = DataObject.DEFAULT_VERSION;
52
53     public DataRow(Map JavaDoc map) {
54         super(map);
55     }
56
57     public DataRow(int initialCapacity) {
58         super(initialCapacity);
59     }
60
61     public long getVersion() {
62         return version;
63     }
64
65     public long getReplacesVersion() {
66         return replacesVersion;
67     }
68
69     /**
70      * Sets the version of DataRow replaced by this one in the store.
71      */

72     public void setReplacesVersion(long replacesVersion) {
73         this.replacesVersion = replacesVersion;
74     }
75
76     /**
77      * Builds a new DataRow, merging changes from <code>diff</code> parameter with data
78      * contained in this DataRow.
79      */

80     public DataRow applyDiff(DataRow diff) {
81         DataRow merged = new DataRow(this);
82
83         Iterator JavaDoc it = diff.entrySet().iterator();
84         while (it.hasNext()) {
85             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
86             merged.put(entry.getKey(), entry.getValue());
87         }
88
89         return merged;
90     }
91
92     /**
93      * Creates a DataRow that contains only the keys that have values that differ between
94      * this object and <code>row</code> parameter. Diff values are taken from the
95      * <code>row</code> parameter. It is assumed that key sets are compatible in both
96      * rows (e.g. they represent snapshots for the same entity). Returns null if no
97      * differences are found.
98      */

99     public DataRow createDiff(DataRow row) {
100
101         // build a diff...
102
DataRow diff = null;
103
104         Iterator JavaDoc entries = entrySet().iterator();
105         while (entries.hasNext()) {
106             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) entries.next();
107
108             Object JavaDoc key = entry.getKey();
109             Object JavaDoc currentValue = entry.getValue();
110             Object JavaDoc rowValue = row.get(key);
111
112             if (!Util.nullSafeEquals(currentValue, rowValue)) {
113                 if (diff == null) {
114                     diff = new DataRow(this.size());
115                 }
116                 diff.put(key, rowValue);
117             }
118         }
119
120         return diff;
121     }
122
123     /**
124      * Creates an ObjectId from the values in the snapshot. If needed attributes are
125      * missing in a snapshot, CayenneRuntimeException is thrown.
126      */

127     // TODO: andrus, 5/25/2006 - deprecate this method - it is unused
128
public ObjectId createObjectId(ObjEntity entity) {
129         return createObjectId(entity.getName(), entity.getDbEntity());
130     }
131
132     // TODO: andrus, 5/25/2006 - deprecate this method - it is unused
133
public ObjectId createObjectId(String JavaDoc entityName, DbEntity entity) {
134         return createObjectId(entityName, entity, null);
135     }
136
137     /**
138      * Returns an ObjectId of an object on the other side of the to-one relationship, for
139      * this DataRow representing a source of relationship. Returns null if snapshot FK
140      * columns indicate a null to-one relationship.
141      */

142     public ObjectId createTargetObjectId(String JavaDoc entityName, DbRelationship relationship) {
143
144         if (relationship.isToMany()) {
145             throw new CayenneRuntimeException("Only 'to one' can have a target ObjectId.");
146         }
147
148         Map JavaDoc target = relationship.targetPkSnapshotWithSrcSnapshot(this);
149         return (target != null) ? new ObjectId(entityName, target) : null;
150     }
151
152     /**
153      * Extracts PK columns prefixed with some path. If namePrefix is null or empty, no
154      * prefixing is done.
155      * <p>
156      * Prefixing is useful when extracting an ObjectId of a target row from a row obtained
157      * via prefetching. namePrefix must omit the "db:" prefix and must end with ".", e.g.
158      * "TO_ARTIST.PAINTING_ARRAY."
159      * </p>
160      *
161      * @since 1.2
162      */

163     // TODO: andrus, 5/25/2006 - deprecate this method - it is unused
164
public ObjectId createObjectId(String JavaDoc entityName, DbEntity entity, String JavaDoc namePrefix) {
165
166         boolean prefix = namePrefix != null && namePrefix.length() > 0;
167
168         // ... handle special case - PK.size == 1
169
// use some not-so-significant optimizations...
170

171         List JavaDoc pk = entity.getPrimaryKey();
172         if (pk.size() == 1) {
173             DbAttribute attribute = (DbAttribute) pk.get(0);
174
175             String JavaDoc key = (prefix) ? namePrefix + attribute.getName() : attribute
176                     .getName();
177
178             Object JavaDoc val = this.get(key);
179             if (val == null) {
180                 throw new CayenneRuntimeException("Null value for '"
181                         + key
182                         + "'. Snapshot: "
183                         + this
184                         + ". Prefix: "
185                         + namePrefix);
186             }
187
188             // PUT without a prefix
189
return new ObjectId(entityName, attribute.getName(), val);
190         }
191
192         // ... handle generic case - PK.size > 1
193

194         Map JavaDoc idMap = new HashMap JavaDoc(pk.size() * 2);
195         Iterator JavaDoc it = pk.iterator();
196         while (it.hasNext()) {
197             DbAttribute attribute = (DbAttribute) it.next();
198
199             String JavaDoc key = (prefix) ? namePrefix + attribute.getName() : attribute
200                     .getName();
201
202             Object JavaDoc val = this.get(key);
203             if (val == null) {
204                 throw new CayenneRuntimeException("Null value for '"
205                         + key
206                         + "'. Snapshot: "
207                         + this
208                         + ". Prefix: "
209                         + namePrefix);
210             }
211
212             // PUT without a prefix
213
idMap.put(attribute.getName(), val);
214         }
215
216         return new ObjectId(entityName, idMap);
217     }
218
219     public String JavaDoc toString() {
220         return new ToStringBuilder(this).append("values", super.toString()).append(
221                 " version",
222                 version).append(" replaces", replacesVersion).toString();
223     }
224 }
225
Popular Tags