KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > map > Entity


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.map;
57
58 import java.util.Collection JavaDoc;
59 import java.util.Collections JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.SortedMap JavaDoc;
62 import java.util.StringTokenizer JavaDoc;
63
64 import org.objectstyle.cayenne.CayenneRuntimeException;
65 import org.objectstyle.cayenne.exp.Expression;
66 import org.objectstyle.cayenne.exp.ExpressionException;
67 import org.objectstyle.cayenne.util.CayenneMap;
68
69 /**
70  * An Entity is an abstract descriptor for an entity mapping concept.
71  * Entity can represent either a descriptor of database table or
72  * a persistent object.
73  *
74  * @author Andrei Adamchik
75  */

76 public abstract class Entity extends MapObject {
77     public static final String JavaDoc PATH_SEPARATOR = ".";
78
79     // ====================================================
80
// Attributes
81
// ====================================================
82
protected CayenneMap attributes = new CayenneMap(this);
83     // read-through reference for public access
84
protected SortedMap JavaDoc attributesMapRef = Collections.unmodifiableSortedMap(attributes);
85     // read-through reference for public access
86
protected Collection JavaDoc attributesRef =
87         Collections.unmodifiableCollection(attributes.values());
88
89     // ====================================================
90
// Relationships
91
// ====================================================
92
protected CayenneMap relationships = new CayenneMap(this);
93     // read-through reference for public access
94
protected SortedMap JavaDoc relationshipsMapRef =
95         Collections.unmodifiableSortedMap(relationships);
96     // read-through reference for public access
97
protected Collection JavaDoc relationshipsRef =
98         Collections.unmodifiableCollection(relationships.values());
99
100     /**
101      * @return parent DataMap of this entity.
102      */

103     public DataMap getDataMap() {
104         return (DataMap) getParent();
105     }
106
107     /**
108      * Sets parent DataMap of this entity.
109      */

110     public void setDataMap(DataMap dataMap) {
111         this.setParent(dataMap);
112     }
113
114     /**
115      * Returns attribute with name <code>attrName</code>.
116      * Will return null if no attribute with this name exists.
117      */

118     public Attribute getAttribute(String JavaDoc attrName) {
119         return (Attribute) attributes.get(attrName);
120     }
121
122     /**
123      * Adds new attribute to the entity. If attribute has no name,
124      * IllegalArgumentException is thrown.
125      *
126      * Also sets <code>attr</code>'s entity to be this entity.
127      */

128     public void addAttribute(Attribute attr) {
129         if (attr.getName() == null) {
130             throw new IllegalArgumentException JavaDoc("Attempt to insert unnamed attribute.");
131         }
132
133         attributes.put(attr.getName(), attr);
134     }
135
136     /** Removes an attribute named <code>attrName</code>.*/
137     public void removeAttribute(String JavaDoc attrName) {
138         attributes.remove(attrName);
139     }
140
141     public void clearAttributes() {
142         attributes.clear();
143     }
144
145     /**
146      * Returns relationship with name <code>relName</code>.
147      * Will return null if no relationship with this name
148      * exists in the entity.
149      */

150     public Relationship getRelationship(String JavaDoc relName) {
151         return (Relationship) relationships.get(relName);
152     }
153
154     /** Adds new relationship to the entity. */
155     public void addRelationship(Relationship rel) {
156         relationships.put(rel.getName(), rel);
157     }
158
159     /** Removes a relationship named <code>attrName</code>.*/
160     public void removeRelationship(String JavaDoc relName) {
161         relationships.remove(relName);
162     }
163
164     public void clearRelationships() {
165         relationships.clear();
166     }
167
168     /**
169      * Returns a map of relationships sorted by name.
170      */

171     public SortedMap JavaDoc getRelationshipMap() {
172         return relationshipsMapRef;
173     }
174
175     /**
176      * Returns a relationship that has a specified entity as a target.
177      * If there is more than one relationship for the same target,
178      * it is unpredictable which one will be returned.
179      *
180      * @since 1.1
181      */

182     public Relationship getAnyRelationship(Entity targetEntity) {
183         Collection JavaDoc relationships = getRelationships();
184         if (relationships.isEmpty()) {
185             return null;
186         }
187
188         Iterator JavaDoc it = relationships.iterator();
189         while (it.hasNext()) {
190             Relationship r = (Relationship) it.next();
191             if (r.getTargetEntity() == targetEntity) {
192                 return r;
193             }
194         }
195         return null;
196     }
197
198     /**
199      * Returns a collection of Relationships that exist in this entity.
200      */

201     public Collection JavaDoc getRelationships() {
202         return relationshipsRef;
203     }
204
205     /**
206      * Returns entity attributes as an unmodifiable map. Since 1.1 returns
207      * a SortedMap.
208      */

209     public SortedMap JavaDoc getAttributeMap() {
210         return attributesMapRef;
211     }
212
213     /**
214      * Returns entity attributes.
215      */

216     public Collection JavaDoc getAttributes() {
217         return attributesRef;
218     }
219
220     /**
221      * Translates Expression rooted in this entity to an analogous expression
222      * rooted in related entity.
223      *
224      * @since 1.1
225      */

226     public abstract Expression translateToRelatedEntity(
227         Expression expression,
228         String JavaDoc relationshipPath);
229
230     /**
231      * Convenience method returning the last component in the path iterator.
232      *
233      * @since 1.1
234      * @see #resolvePathComponents(Expression)
235      */

236     public Object JavaDoc lastPathComponent(Expression pathExp) {
237         Object JavaDoc last = null;
238         Iterator JavaDoc it = resolvePathComponents(pathExp);
239         while (it.hasNext()) {
240             last = it.next();
241         }
242
243         return last;
244     }
245
246     /**
247      * Processes expression <code>pathExp</code> and returns an Iterator
248      * of path components that contains a sequence of Attributes and Relationships.
249      * Note that if path is invalid and can not be resolved from this entity,
250      * this method will still return an Iterator, but an attempt to read the first
251      * invalid path component will result in ExpressionException.
252      */

253     public abstract Iterator JavaDoc resolvePathComponents(Expression pathExp)
254         throws ExpressionException;
255
256     /**
257      * Returns an Iterator over the path components that contains a sequence of
258      * Attributes and Relationships. Note that if path is invalid and can not be
259      * resolved from this entity, this method will still return an Iterator,
260      * but an attempt to read the first invalid path component will result in
261      * ExpressionException.
262      */

263     public Iterator JavaDoc resolvePathComponents(String JavaDoc path) throws ExpressionException {
264         return new PathIterator(path);
265     }
266
267     // An iterator resolving mapping components represented by the path string.
268
// This entity is assumed to be the root of the path.
269
final class PathIterator implements Iterator JavaDoc {
270
271         private StringTokenizer JavaDoc toks;
272         private Entity currentEnt;
273         private String JavaDoc path;
274
275         PathIterator(String JavaDoc path) {
276             super();
277             this.currentEnt = Entity.this;
278             this.toks = new StringTokenizer JavaDoc(path, PATH_SEPARATOR);
279             this.path = path;
280         }
281
282         public boolean hasNext() {
283             return toks.hasMoreTokens();
284         }
285
286         public Object JavaDoc next() {
287             String JavaDoc pathComp = toks.nextToken();
288
289             // see if this is an attribute
290
Attribute attr = currentEnt.getAttribute(pathComp);
291             if (attr != null) {
292                 // do a sanity check...
293
if (toks.hasMoreTokens()) {
294                     throw new ExpressionException(
295                         "Attribute must be the last component of the path: '"
296                             + pathComp
297                             + "'.",
298                         path,
299                         null);
300                 }
301
302                 return attr;
303             }
304
305             Relationship rel = currentEnt.getRelationship(pathComp);
306             if (rel != null) {
307                 currentEnt = rel.getTargetEntity();
308                 return rel;
309             }
310
311             // build error message
312
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
313             buf
314                 .append("Can't resolve path component: [")
315                 .append(currentEnt.getName())
316                 .append('.')
317                 .append(pathComp)
318                 .append("].");
319             throw new ExpressionException(buf.toString(), path, null);
320         }
321
322         public void remove() {
323             throw new UnsupportedOperationException JavaDoc("'remove' operation is not supported.");
324         }
325     }
326
327     final MappingNamespace getNonNullNamespace() {
328         MappingNamespace parent = (MappingNamespace) getParent();
329         if (parent == null) {
330             throw new CayenneRuntimeException(
331                 "Entity '"
332                     + getName()
333                     + "' has no parent MappingNamespace (such as DataMap)");
334         }
335
336         return parent;
337     }
338 }
339
Popular Tags