KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > access > EntityDescriptor


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.access;
57
58 import java.util.Collection JavaDoc;
59 import java.util.HashMap JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.Map JavaDoc;
62
63 import org.apache.commons.collections.Factory;
64 import org.apache.commons.collections.Transformer;
65 import org.objectstyle.cayenne.CayenneRuntimeException;
66 import org.objectstyle.cayenne.DataObject;
67 import org.objectstyle.cayenne.ObjectId;
68 import org.objectstyle.cayenne.dba.PkGenerator;
69 import org.objectstyle.cayenne.map.DbEntity;
70 import org.objectstyle.cayenne.map.ObjEntity;
71
72 /**
73  * A utility class that provides a set of transformers to build snapshots from
74  * DataObjects. One important feature of EntityDescriptor is the ability to provide
75  * deferred snapshots that contain factories for unresolved keys.
76  *
77  * @author Andrei Adamchik
78  * @since 1.2
79  */

80 class EntityDescriptor {
81
82     DataNode node;
83     ObjEntity entity;
84     DbEntity dbEntity;
85     Map JavaDoc snapshotTransformers;
86
87     EntityDescriptor(DataNode node, ObjEntity entity) {
88         this.node = node;
89         this.entity = entity;
90         this.dbEntity = entity.getDbEntity();
91         initTransformers();
92     }
93
94     private void initTransformers() {
95
96         Collection JavaDoc attributes = dbEntity.getAttributes();
97         this.snapshotTransformers = new HashMap JavaDoc((int) (attributes.size() * 4.00 / 3.00));
98
99         // init transformers for attributes coming from object...
100

101         Iterator JavaDoc it = entity.getAttributes().iterator();
102         while (it.hasNext()) {
103             // ObjAttribute attribute = (ObjAttribute) it.next();
104

105         }
106     }
107
108     /**
109      * Creates an object snapshot replacing unknown values with
110      * org.apache.commons.collections.Factory instances that allow to defer value
111      * resolution.
112      */

113     Map JavaDoc deferredSnapshot(DataObject object) {
114         Map JavaDoc snapshot = new HashMap JavaDoc((int) (snapshotTransformers.size() * 4.00 / 3.00));
115         Iterator JavaDoc it = snapshotTransformers.entrySet().iterator();
116         while (it.hasNext()) {
117             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
118             snapshot.put(entry.getKey(), ((Transformer) entry.getValue())
119                     .transform(object));
120         }
121
122         return snapshot;
123     }
124
125     Object JavaDoc deferredSnapshotValue(DataObject object, String JavaDoc dbAttributeName) {
126         Transformer transformer = (Transformer) snapshotTransformers
127                 .get(dbAttributeName);
128
129         if (transformer == null) {
130             throw new CayenneRuntimeException("Invalid DbAttribute: " + dbAttributeName);
131         }
132
133         return transformer.transform(object);
134     }
135
136     // ==========================================================
137
// Transformers
138
// ==========================================================
139

140     abstract class DataObjectTransformer implements Transformer {
141
142         public Object JavaDoc transform(Object JavaDoc input) {
143             if (input instanceof DataObject) {
144                 return (DataObject) transformDataObject((DataObject) input);
145             }
146
147             throw new CayenneRuntimeException("Invalid input: " + input);
148         }
149
150         protected abstract Object JavaDoc transformDataObject(DataObject object);
151     }
152
153     // passes object to all transformers in sequence until one evaluates to non-null
154
final class NullPredicateTransformer extends DataObjectTransformer {
155
156         String JavaDoc attributeName;
157         DataObjectTransformer[] transformers;
158
159         NullPredicateTransformer(DataObjectTransformer[] transformers,
160                 String JavaDoc attributeName) {
161             this.transformers = transformers;
162             this.attributeName = attributeName;
163         }
164
165         protected Object JavaDoc transformDataObject(DataObject object) {
166             for (int i = 0; i < transformers.length; i++) {
167                 Object JavaDoc value = transformers[i].transformDataObject(object);
168                 if (value != null) {
169                     return value;
170                 }
171             }
172
173             throw new CayenneRuntimeException("Problem getting snapshot value for "
174                     + object.getClass()
175                     + ", attribute name: "
176                     + attributeName);
177         }
178     }
179
180     final class ObjectPropertyTransformer extends DataObjectTransformer {
181
182         String JavaDoc property;
183
184         ObjectPropertyTransformer(String JavaDoc property) {
185             this.property = property;
186         }
187
188         protected Object JavaDoc transformDataObject(DataObject object) {
189             return object.readPropertyDirectly(property);
190         }
191     }
192
193     final class PropagatedValueTransformer extends DataObjectTransformer {
194
195         String JavaDoc masterProperty;
196         String JavaDoc masterIDKey;
197         boolean deferred;
198         boolean required;
199
200         PropagatedValueTransformer(String JavaDoc masterProperty, String JavaDoc masterIDKey,
201                 boolean required, boolean deferred) {
202             this.masterIDKey = masterIDKey;
203             this.masterProperty = masterProperty;
204             this.required = required;
205             this.deferred = deferred;
206         }
207
208         protected Object JavaDoc transformDataObject(DataObject object) {
209
210             DataObject targetDo = (DataObject) object
211                     .readPropertyDirectly(masterProperty);
212
213             if (targetDo == null) {
214                 throw new CayenneRuntimeException(
215                         "Problem extracting master PK value - null master object for "
216                                 + object.getClass()
217                                 + "."
218                                 + masterProperty);
219             }
220
221             ObjectId targetKey = targetDo.getObjectId();
222
223             if (deferred) {
224                 return new DeferredIDValueFactory(targetKey, masterIDKey);
225             }
226
227             Object JavaDoc value = targetKey.getValueForAttribute(masterIDKey);
228
229             if (required && value == null) {
230                 throw new CayenneRuntimeException(
231                         "Problem extracting master PK value - null master PK "
232                                 + object.getClass()
233                                 + "."
234                                 + masterProperty);
235             }
236
237             return value;
238         }
239     }
240
241     final class CayenneGeneratedPKTransformer extends DataObjectTransformer {
242
243         PkGenerator generator;
244
245         CayenneGeneratedPKTransformer(PkGenerator generator) {
246             this.generator = generator;
247         }
248
249         protected Object JavaDoc transformDataObject(DataObject object) {
250             try {
251                 return generator.generatePkForDbEntity(node, dbEntity);
252             }
253             catch (Exception JavaDoc ex) {
254                 throw new CayenneRuntimeException("Error generating PK: "
255                         + ex.getMessage(), ex);
256             }
257         }
258     }
259
260     // ==========================================================
261
// Factories [used for deferred value creation]
262
// ==========================================================
263

264     final static class DeferredIDValueFactory implements Factory {
265
266         ObjectId objectID;
267         String JavaDoc idKey;
268
269         DeferredIDValueFactory(ObjectId objectID, String JavaDoc idKey) {
270             this.objectID = objectID;
271             this.idKey = idKey;
272         }
273
274         public Object JavaDoc create() {
275             if (!objectID.isReplacementIdAttached()) {
276                 throw new CayenneRuntimeException("Replacement value for key '"
277                         + idKey
278                         + "' is not available in ObjectId "
279                         + objectID);
280             }
281
282             Map JavaDoc replacementId = objectID.getReplacementIdMap();
283             Object JavaDoc value = replacementId.get(idKey);
284             if (value == null) {
285                 throw new CayenneRuntimeException("Replacement value for key '"
286                         + idKey
287                         + "' is not available in ObjectId "
288                         + objectID);
289             }
290
291             return value;
292         }
293     }
294 }
Popular Tags