KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > reflect > PersistentDescriptor


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 package org.apache.cayenne.reflect;
20
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import org.apache.cayenne.CayenneRuntimeException;
28 import org.apache.cayenne.PersistenceState;
29 import org.apache.cayenne.map.ObjAttribute;
30 import org.apache.cayenne.map.ObjEntity;
31 import org.apache.commons.collections.IteratorUtils;
32
33 /**
34  * A default ClassDescriptor implementation for persistent objects.
35  *
36  * @since 3.0
37  * @author Andrus Adamchik
38  */

39 public class PersistentDescriptor implements ClassDescriptor {
40
41     static final Integer JavaDoc TRANSIENT_STATE = new Integer JavaDoc(PersistenceState.TRANSIENT);
42     static final Integer JavaDoc HOLLOW_STATE = new Integer JavaDoc(PersistenceState.HOLLOW);
43     static final Integer JavaDoc COMMITTED_STATE = new Integer JavaDoc(PersistenceState.COMMITTED);
44
45     protected ClassDescriptor superclassDescriptor;
46
47     // compiled properties ...
48
protected Class JavaDoc objectClass;
49     protected Map JavaDoc declaredProperties;
50     protected Map JavaDoc subclassDescriptors;
51     protected Accessor persistenceStateAccessor;
52
53     protected ObjEntity entity;
54
55     protected Collection JavaDoc declaredIdProperties;
56
57     /**
58      * Creates a PersistentDescriptor.
59      */

60     public PersistentDescriptor() {
61         this.declaredProperties = new HashMap JavaDoc();
62         this.subclassDescriptors = new HashMap JavaDoc();
63     }
64
65     /**
66      * Registers a property. This method is useful to customize default ClassDescriptor
67      * generated from ObjEntity by adding new properties or overriding the standard ones.
68      */

69     public void addDeclaredProperty(Property property) {
70         declaredProperties.put(property.getName(), property);
71
72         if (property instanceof AttributeProperty) {
73             ObjAttribute attribute = ((AttributeProperty) property).getAttribute();
74             if (attribute.getDbAttributeName() != null
75                     && attribute.getDbAttribute().isPrimaryKey()) {
76
77                 if (declaredIdProperties == null) {
78                     declaredIdProperties = new ArrayList JavaDoc(2);
79                 }
80
81                 declaredIdProperties.add(property);
82             }
83         }
84     }
85
86     /**
87      * Removes declared property. This method can be used to customize default
88      * ClassDescriptor generated from ObjEntity.
89      */

90     public void removeDeclaredProperty(String JavaDoc propertyName) {
91         Object JavaDoc removed = declaredProperties.remove(propertyName);
92
93         if (declaredIdProperties != null && removed != null) {
94             declaredIdProperties.remove(removed);
95         }
96     }
97
98     public void addSubclassDescriptor(ClassDescriptor subclassDescriptor) {
99         subclassDescriptors.put(
100                 subclassDescriptor.getEntity().getClassName(),
101                 subclassDescriptor);
102     }
103
104     public ObjEntity getEntity() {
105         return entity;
106     }
107
108     public boolean isFault(Object JavaDoc object) {
109         if (superclassDescriptor != null) {
110             return superclassDescriptor.isFault(object);
111         }
112
113         if (object == null) {
114             return false;
115         }
116
117         return HOLLOW_STATE.equals(persistenceStateAccessor.getValue(object));
118     }
119
120     public Class JavaDoc getObjectClass() {
121         return objectClass;
122     }
123
124     void setObjectClass(Class JavaDoc objectClass) {
125         this.objectClass = objectClass;
126     }
127
128     public ClassDescriptor getSubclassDescriptor(Class JavaDoc objectClass) {
129         if (objectClass == null) {
130             throw new IllegalArgumentException JavaDoc("Null objectClass");
131         }
132
133         if (subclassDescriptors.isEmpty()) {
134             return this;
135         }
136
137         ClassDescriptor subclassDescriptor = (ClassDescriptor) subclassDescriptors
138                 .get(objectClass.getName());
139
140         // ascend via the class hierarchy (only doing it if there are multiple choices)
141
if (subclassDescriptor == null) {
142             Class JavaDoc currentClass = objectClass;
143             while (subclassDescriptor == null
144                     && (currentClass = currentClass.getSuperclass()) != null) {
145                 subclassDescriptor = (ClassDescriptor) subclassDescriptors
146                         .get(currentClass.getName());
147             }
148         }
149
150         return subclassDescriptor != null ? subclassDescriptor : this;
151     }
152
153     /**
154      * @deprecated since 3.0. Use {@link #visitProperties(PropertyVisitor)} method
155      * instead.
156      */

157     public Iterator JavaDoc getProperties() {
158         Iterator JavaDoc declaredIt = IteratorUtils.unmodifiableIterator(declaredProperties
159                 .values()
160                 .iterator());
161
162         if (getSuperclassDescriptor() == null) {
163             return declaredIt;
164         }
165         else {
166             return IteratorUtils.chainedIterator(
167                     superclassDescriptor.getProperties(),
168                     declaredIt);
169         }
170     }
171
172     public Iterator JavaDoc getIdProperties() {
173
174         Iterator JavaDoc it = null;
175
176         if (getSuperclassDescriptor() != null) {
177             it = getSuperclassDescriptor().getIdProperties();
178         }
179
180         if (declaredIdProperties != null) {
181             it = (it != null) ? IteratorUtils.chainedIterator(it, declaredIdProperties
182                     .iterator()) : declaredIdProperties.iterator();
183         }
184
185         return it != null ? it : IteratorUtils.EMPTY_ITERATOR;
186     }
187
188     /**
189      * Recursively looks up property descriptor in this class descriptor and all
190      * superclass descriptors.
191      */

192     public Property getProperty(String JavaDoc propertyName) {
193         Property property = getDeclaredProperty(propertyName);
194
195         if (property == null && superclassDescriptor != null) {
196             property = superclassDescriptor.getProperty(propertyName);
197         }
198
199         return property;
200     }
201
202     public Property getDeclaredProperty(String JavaDoc propertyName) {
203         return (Property) declaredProperties.get(propertyName);
204     }
205
206     /**
207      * Returns a descriptor of the mapped superclass or null if the descriptor's entity
208      * sits at the top of inheritance hierarchy.
209      */

210     public ClassDescriptor getSuperclassDescriptor() {
211         return superclassDescriptor;
212     }
213
214     /**
215      * Creates a new instance of a class described by this object.
216      */

217     public Object JavaDoc createObject() {
218         if (objectClass == null) {
219             throw new NullPointerException JavaDoc(
220                     "Null objectClass. Descriptor wasn't initialized properly.");
221         }
222
223         try {
224             return objectClass.newInstance();
225         }
226         catch (Throwable JavaDoc e) {
227             throw new CayenneRuntimeException("Error creating object of class '"
228                     + objectClass.getName()
229                     + "'", e);
230         }
231     }
232
233     /**
234      * Invokes 'prepareForAccess' of a super descriptor and then invokes
235      * 'prepareForAccess' of each declared property.
236      */

237     public void injectValueHolders(Object JavaDoc object) throws PropertyException {
238
239         // do super first
240
if (getSuperclassDescriptor() != null) {
241             getSuperclassDescriptor().injectValueHolders(object);
242         }
243
244         Iterator JavaDoc it = declaredProperties.values().iterator();
245         while (it.hasNext()) {
246             Property property = (Property) it.next();
247             property.injectValueHolder(object);
248         }
249     }
250
251     /**
252      * Copies object properties from one object to another. Invokes 'shallowCopy' of a
253      * super descriptor and then invokes 'shallowCopy' of each declared property.
254      */

255     public void shallowMerge(final Object JavaDoc from, final Object JavaDoc to) throws PropertyException {
256
257         visitProperties(new PropertyVisitor() {
258
259             public boolean visitAttribute(AttributeProperty property) {
260                 property.writePropertyDirectly(
261                         to,
262                         property.readPropertyDirectly(to),
263                         property.readPropertyDirectly(from));
264                 return true;
265             }
266
267             public boolean visitToOne(ToOneProperty property) {
268                 property.invalidate(to);
269                 return true;
270             }
271
272             public boolean visitToMany(ToManyProperty property) {
273                 return true;
274             }
275         });
276     }
277
278     /**
279      * @since 3.0
280      */

281     public boolean visitDeclaredProperties(PropertyVisitor visitor) {
282         Iterator JavaDoc it = declaredProperties.values().iterator();
283         while (it.hasNext()) {
284             Property next = (Property) it.next();
285             if (!next.visit(visitor)) {
286                 return false;
287             }
288         }
289
290         return true;
291     }
292
293     /**
294      * @since 3.0
295      */

296     public boolean visitAllProperties(PropertyVisitor visitor) {
297         if (!visitProperties(visitor)) {
298             return false;
299         }
300
301         if (!subclassDescriptors.isEmpty()) {
302             Iterator JavaDoc it = subclassDescriptors.values().iterator();
303             while (it.hasNext()) {
304                 ClassDescriptor next = (ClassDescriptor) it.next();
305                 if (!next.visitDeclaredProperties(visitor)) {
306                     return false;
307                 }
308             }
309         }
310
311         return true;
312     }
313
314     public boolean visitProperties(PropertyVisitor visitor) {
315         if (superclassDescriptor != null
316                 && !superclassDescriptor.visitProperties(visitor)) {
317             return false;
318         }
319
320         return visitDeclaredProperties(visitor);
321     }
322
323     public void setPersistenceStateAccessor(Accessor persistenceStateAccessor) {
324         this.persistenceStateAccessor = persistenceStateAccessor;
325     }
326
327     public void setEntity(ObjEntity entity) {
328         this.entity = entity;
329     }
330
331     public void setSuperclassDescriptor(ClassDescriptor superclassDescriptor) {
332         this.superclassDescriptor = superclassDescriptor;
333     }
334 }
335
Popular Tags