KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > api > persistence > model > jdo > RelationshipElement


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * RelationshipElement.java
26  *
27  * Created on February 29, 2000, 2:30 PM
28  */

29
30 package com.sun.jdo.api.persistence.model.jdo;
31
32 import com.sun.jdo.api.persistence.model.Model;
33 import com.sun.jdo.api.persistence.model.ModelException;
34 import com.sun.jdo.spi.persistence.utility.I18NHelper;
35
36 /* TODO:
37     1. throw (Model or IllegalArgument)Exception on set illegal constant values?
38         also applies to PersistenceClass, PersistenceField classes
39     2. enforce/validate collection/bound combinations, document that other piece
40         only used when ...
41     3. document default values for all constants (should that go in impl docs?)
42         also applies to PersistenceClass, PersistenceField classes
43     4. document support collection classes? are we supporting this at all or
44         does the user have to type that directly into the code?
45  */

46
47 /**
48  *
49  * @author raccah
50  * @version %I%
51  */

52 public class RelationshipElement extends PersistenceFieldElement
53 {
54     /** Constant representing no action. */
55     public static final int NONE_ACTION = 0;
56
57     /** Constant representing nullify action. */
58     public static final int NULLIFY_ACTION = 1;
59
60     /** Constant representing restrict action. */
61     public static final int RESTRICT_ACTION = 2;
62
63     /** Constant representing cascade action. */
64     public static final int CASCADE_ACTION = 3;
65
66     /** Constant representing aggregate action. */
67     public static final int AGGREGATE_ACTION = 4;
68
69     /** Create new RelationshipElement with no implementation.
70      * This constructor should only be used for cloning and archiving.
71      */

72     public RelationshipElement ()
73     {
74         this(null, null);
75     }
76
77     /** Create new RelationshipElement with the provided implementation. The
78      * implementation is responsible for storing all properties of the object.
79      * @param impl the implementation to use
80      * @param declaringClass the class to attach to
81      */

82     public RelationshipElement (RelationshipElement.Impl impl,
83         PersistenceClassElement declaringClass)
84     {
85         super(impl, declaringClass);
86     }
87
88     /** @return implemetation factory for this relationship
89      */

90     final Impl getRelationshipImpl () { return (Impl)getImpl(); }
91
92     //================ Update and Delete Semantics ============================
93

94     /** Get the update action for this relationship element.
95      * @return the update action, one of {@link #NONE_ACTION},
96      * {@link #NULLIFY_ACTION}, {@link #RESTRICT_ACTION},
97      * {@link #CASCADE_ACTION}, or {@link #AGGREGATE_ACTION}
98      */

99     public int getUpdateAction ()
100     {
101         return getRelationshipImpl().getUpdateAction();
102     }
103
104     /** Set the update action for this relationship element.
105      * @param action - an integer indicating the update action, one of:
106      * {@link #NONE_ACTION}, {@link #NULLIFY_ACTION}, {@link #RESTRICT_ACTION},
107      * {@link #CASCADE_ACTION}, or {@link #AGGREGATE_ACTION}
108      * @exception ModelException if impossible
109      */

110     public void setUpdateAction (int action) throws ModelException
111     {
112         if ((action < NONE_ACTION) || (action > AGGREGATE_ACTION))
113         {
114             throw new ModelException(I18NHelper.getMessage(getMessages(),
115                 "jdo.relationship.update_action_invalid", action)); // NOI18N
116
}
117
118         getRelationshipImpl().setUpdateAction(action);
119     }
120
121     /** Get the delete action for this relationship element.
122      * @return the delete action, one of {@link #NONE_ACTION},
123      * {@link #NULLIFY_ACTION}, {@link #RESTRICT_ACTION},
124      * {@link #CASCADE_ACTION}, or {@link #AGGREGATE_ACTION}
125      */

126     public int getDeleteAction ()
127     {
128         return getRelationshipImpl().getDeleteAction();
129     }
130
131     /** Set the delete action for this relationship element.
132      * @param action - an integer indicating the delete action, one of:
133      * {@link #NONE_ACTION}, {@link #NULLIFY_ACTION}, {@link #RESTRICT_ACTION},
134      * {@link #CASCADE_ACTION}, or {@link #AGGREGATE_ACTION}
135      * @exception ModelException if impossible
136      */

137     public void setDeleteAction (int action) throws ModelException
138     {
139         if ((action < NONE_ACTION) || (action > AGGREGATE_ACTION))
140         {
141             throw new ModelException(I18NHelper.getMessage(getMessages(),
142                 "jdo.relationship.delete_action_invalid", action)); // NOI18N
143
}
144
145         getRelationshipImpl().setDeleteAction(action);
146     }
147
148     /** Determines whether this relationship element should prefetch or not.
149      * @return <code>true</code> if the relationship should prefetch,
150      * <code>false</code> otherwise
151      */

152     public boolean isPrefetch ()
153     {
154         return getRelationshipImpl().isPrefetch();
155     }
156
157     /** Set whether this relationship element should prefetch or not.
158      * @param flag - if <code>true</code>, the relationship is set to prefetch;
159      * otherwise, it is not
160      * @exception ModelException if impossible
161      */

162     public void setPrefetch (boolean flag) throws ModelException
163     {
164         getRelationshipImpl().setPrefetch(flag);
165     }
166
167     //================ Cardinality Bounds ============================
168

169     /** Get the lower cardinality bound for this relationship element.
170      * @return the lower cardinality bound
171      */

172     public int getLowerBound ()
173     {
174         return getRelationshipImpl().getLowerBound();
175     }
176
177     /** Set the lower cardinality bound for this relationship element.
178      * @param lowerBound - an integer indicating the lower cardinality bound
179      * @exception ModelException if impossible
180      */

181     public void setLowerBound (int lowerBound) throws ModelException
182     {
183         if ((lowerBound > getUpperBound()) || (lowerBound < 0))
184         {
185             throw new ModelException(I18NHelper.getMessage(getMessages(),
186                 "jdo.relationship.lower_cardinality_invalid")); // NOI18N
187
}
188
189         getRelationshipImpl().setLowerBound(lowerBound);
190     }
191
192     /** Get the upper cardinality bound for this relationship element. Returns
193      * {@link java.lang.Integer#MAX_VALUE} for <code>n</code>
194      * @return the upper cardinality bound
195      */

196     public int getUpperBound ()
197     {
198         return getRelationshipImpl().getUpperBound();
199     }
200
201     /** Set the upper cardinality bound for this relationship element.
202      * @param upperBound - an integer indicating the upper cardinality bound
203      * (use {@link java.lang.Integer#MAX_VALUE} for <code>n</code>)
204      * @exception ModelException if impossible
205      */

206     public void setUpperBound (int upperBound) throws ModelException
207     {
208         if ((upperBound < getLowerBound()) || (upperBound <= 0))
209         {
210             throw new ModelException(I18NHelper.getMessage(getMessages(),
211                 "jdo.relationship.upper_cardinality_invalid")); // NOI18N
212
}
213
214         getRelationshipImpl().setUpperBound(upperBound);
215     }
216
217     //================ Collection Support ============================
218

219     /** Get the collection class (for example Set, List, Vector, etc.)
220      * for this relationship element.
221      * @return the collection class
222      */

223     public String JavaDoc getCollectionClass ()
224     {
225         return getRelationshipImpl().getCollectionClass();
226     }
227
228     /** Set the collection class for this relationship element.
229      * @param collectionClass - a string indicating the type of
230      * collection (for example Set, List, Vector, etc.)
231      * @exception ModelException if impossible
232      */

233     public void setCollectionClass (String JavaDoc collectionClass)
234         throws ModelException
235     {
236         getRelationshipImpl().setCollectionClass(collectionClass);
237     }
238
239     /** Get the element class for this relationship element. If primitive
240      * types are supported, you can use
241      * <code><i>wrapperclass</i>.TYPE.toString()</code> to specify them.
242      * @return the element class
243      */

244     public String JavaDoc getElementClass ()
245     {
246         return getRelationshipImpl().getElementClass();
247     }
248
249     /** Set the element class for this relationship element.
250      * @param elementClass - a string indicating the type of elements in
251      * the collection. If primitive types are supported, you can use
252      * <code><i>wrapperclass</i>.TYPE.toString()</code> to specify them.
253      * @exception ModelException if impossible
254      */

255     public void setElementClass (String JavaDoc elementClass) throws ModelException
256     {
257         getRelationshipImpl().setElementClass(elementClass);
258     }
259
260     //================ Two-way Relationship Support ============================
261

262     // Note that the fact that inverse relationship name (an implementation
263
// detail) is exposed and model is required as an argument for the get/set
264
// methods is an artifact of our current design (i.e. archiver/vertical
265
// split issues, no way to look up a related class without use of the
266
// Model, etc.) and should be removed in the new Orion model
267

268     /** Get the relative name of the inverse relationship field for this
269      * relationship element. In the case of two-way relationships, the two
270      * relationship elements involved are inverses of each other. If this
271      * relationship element does not participate in a two-way relationship,
272      * this returns <code>null</code>. Note that it is possible to have this
273      * method return a value, but because of the combination of related class
274      * and lookup, there may be no corresponding RelationshipElement which can
275      * be found.
276      * @return the relative name of the inverse relationship element
277      * @see #getInverseRelationship
278      */

279     public String JavaDoc getInverseRelationshipName ()
280     {
281         return getRelationshipImpl().getInverseRelationshipName();
282     }
283
284     /** Get the inverse relationship element for this relationship element.
285      * In the case of two-way relationships, the two relationship elements
286      * involved are inverses of each other. If this relationship element does
287      * not participate in a two-way relationship, this returns
288      * <code>null</code>. Note that it is also possible for this method to
289      * return <code>null</code> even if {@link #getInverseRelationshipName}
290      * returns a value because the corresponding RelationshipElement cannot
291      * be found using the combination of related class and lookup (model).
292      * @param model the model object to be used to look it up
293      * @return the inverse relationship element if it exists
294      * @see #getInverseRelationshipName
295      */

296     public RelationshipElement getInverseRelationship (Model model)
297     {
298         String JavaDoc inverseName = getInverseRelationshipName();
299         RelationshipElement inverse = null;
300
301         if ((model != null) && (inverseName != null))
302         {
303             String JavaDoc relatedClass = model.getRelatedClass(this);
304
305             if (relatedClass != null)
306             {
307                 PersistenceClassElement relatedElement =
308                     model.getPersistenceClass(relatedClass);
309
310                 if (relatedElement != null)
311                     inverse = relatedElement.getRelationship(inverseName);
312             }
313         }
314
315         return inverse;
316     }
317
318     /** Set the inverse relationship element for this relationship element.
319      * In the case of two-way relationships, the two relationship elements
320      * involved are inverses of each other.
321      * @param inverseRelationship - a relationship element to be used as the
322      * inverse for this relationship element or <code>null</code> if this
323      * relationship element does not participate in a two-way relationship.
324      * @param model the model object to be used to look up the old inverse so
325      * it can be unset
326      * @exception ModelException if impossible
327      */

328     public void setInverseRelationship (RelationshipElement inverseRelationship,
329         Model model) throws ModelException
330     {
331         RelationshipElement old = getInverseRelationship(model);
332
333         if ((old != inverseRelationship) || ((inverseRelationship == null) &&
334             (getInverseRelationshipName() != null)))
335         {
336             // clear old inverse which still points to here
337
if (old != null)
338             {
339                 RelationshipElement oldInverse =
340                     old.getInverseRelationship(model);
341
342                 if (this.equals(oldInverse))
343                     old.changeInverseRelationship(null);
344             }
345
346             // link from here to new inverse
347
changeInverseRelationship(inverseRelationship);
348
349             // link from new inverse back to here
350
if (inverseRelationship != null)
351                 inverseRelationship.changeInverseRelationship(this);
352         }
353     }
354
355     /** Changes the inverse relationship element for this relationship element.
356      * This method is invoked for both sides from
357      * {@link RelationshipElement#setInverseRelationship} and should handle the
358      * vetoable change events, property change events, and setting the internal
359      * variable.
360      * @param inverseRelationship - a relationship element to be used as the
361      * inverse for this relationship element or <code>null</code> if this
362      * relationship element does not participate in a two-way relationship.
363      * @exception ModelException if impossible
364      */

365     public void changeInverseRelationship (
366         RelationshipElement inverseRelationship) throws ModelException
367     {
368         getRelationshipImpl().changeInverseRelationship(inverseRelationship);
369     }
370
371     /** Pluggable implementation of the storage of relationship element
372      * properties.
373      * @see RelationshipElement#RelationshipElement
374      */

375     public interface Impl extends PersistenceFieldElement.Impl
376     {
377         /** Get the update action for this relationship element.
378          * @return the update action, one of {@link #NONE_ACTION},
379          * {@link #NULLIFY_ACTION}, {@link #RESTRICT_ACTION},
380          * {@link #CASCADE_ACTION}, or {@link #AGGREGATE_ACTION}
381          */

382         public int getUpdateAction ();
383
384         /** Set the update action for this relationship element.
385          * @param action - an integer indicating the update action, one of:
386          * {@link #NONE_ACTION}, {@link #NULLIFY_ACTION},
387          * {@link #RESTRICT_ACTION}, {@link #CASCADE_ACTION}, or
388          * {@link #AGGREGATE_ACTION}
389          * @exception ModelException if impossible
390          */

391         public void setUpdateAction (int action) throws ModelException;
392
393         /** Get the delete action for this relationship element.
394          * @return the delete action, one of {@link #NONE_ACTION},
395          * {@link #NULLIFY_ACTION}, {@link #RESTRICT_ACTION},
396          * {@link #CASCADE_ACTION}, or {@link #AGGREGATE_ACTION}
397          */

398         public int getDeleteAction ();
399
400         /** Set the delete action for this relationship element.
401          * @param action - an integer indicating the delete action, one of:
402          * {@link #NONE_ACTION}, {@link #NULLIFY_ACTION},
403          * {@link #RESTRICT_ACTION}, {@link #CASCADE_ACTION}, or
404          * {@link #AGGREGATE_ACTION}
405          * @exception ModelException if impossible
406          */

407         public void setDeleteAction (int action) throws ModelException;
408
409         /** Determines whether this relationship element should prefetch or not.
410          * @return <code>true</code> if the relationship should prefetch,
411          * <code>false</code> otherwise
412          */

413         public boolean isPrefetch ();
414
415         /** Set whether this relationship element should prefetch or not.
416          * @param flag - if <code>true</code>, the relationship is set to
417          * prefetch; otherwise, it is not
418          * @exception ModelException if impossible
419          */

420         public void setPrefetch (boolean flag) throws ModelException;
421
422         /** Get the lower cardinality bound for this relationship element.
423          * @return the lower cardinality bound
424          */

425         public int getLowerBound ();
426
427         /** Set the lower cardinality bound for this relationship element.
428          * @param lowerBound - an integer indicating the lower cardinality bound
429          * @exception ModelException if impossible
430          */

431         public void setLowerBound (int lowerBound) throws ModelException;
432
433         /** Get the upper cardinality bound for this relationship element.
434          * Returns {@link java.lang.Integer#MAX_VALUE} for <code>n</code>
435          * @return the upper cardinality bound
436          */

437         public int getUpperBound ();
438
439         /** Set the upper cardinality bound for this relationship element.
440          * @param upperBound - an integer indicating the upper cardinality bound
441          * (use {@link java.lang.Integer#MAX_VALUE} for <code>n</code>)
442          * @exception ModelException if impossible
443          */

444         public void setUpperBound (int upperBound) throws ModelException;
445
446         /** Get the collection class (for example Set, List, Vector, etc.)
447          * for this relationship element.
448          * @return the collection class
449          */

450         public String JavaDoc getCollectionClass ();
451
452         /** Set the collection class for this relationship element.
453          * @param collectionClass - a string indicating the type of
454          * collection (for example Set, List, Vector, etc.)
455          * @exception ModelException if impossible
456          */

457         public void setCollectionClass (String JavaDoc collectionClass)
458             throws ModelException;
459
460         /** Get the element class for this relationship element. If primitive
461          * types are supported, you can use
462          * <code><i>wrapperclass</i>.TYPE.toString()</code> to specify them.
463          * @return the element class
464          */

465         public String JavaDoc getElementClass ();
466
467         /** Set the element class for this relationship element.
468          * @param elementClass - a string indicating the type of elements
469          * in the collection. If primitive types are supported, you can use
470          * <code><i>wrapperclass</i>.TYPE.toString()</code> to specify them.
471          * @exception ModelException if impossible
472          */

473         public void setElementClass (String JavaDoc elementClass) throws ModelException;
474
475         /** Get the relative name of the inverse relationship field for this
476          * relationship element. In the case of two-way relationships, the two
477          * relationship elements involved are inverses of each other. If this
478          * relationship element does not participate in a two-way relationship,
479          * this returns <code>null</code>. Note that it is possible to have
480          * this method return a value, but because of the combination of
481          * related class and lookup, there may be no corresponding
482          * RelationshipElement which can be found.
483          * @return the relative name of the inverse relationship element
484          * @see #getInverseRelationship
485          */

486         public String JavaDoc getInverseRelationshipName ();
487
488         /** Changes the inverse relationship element for this relationship
489          * element. This method is invoked for both sides from
490          * {@link RelationshipElement#setInverseRelationship} and should handle
491          * the vetoable change events, property change events, and setting the
492          * internal variable.
493          * @param inverseRelationship - a relationship element to be used as
494          * the inverse for this relationship element or <code>null</code> if
495          * this relationship element does not participate in a two-way
496          * relationship.
497          * @exception ModelException if impossible
498          */

499         public void changeInverseRelationship (
500             RelationshipElement inverseRelationship) throws ModelException;
501     }
502 }
503
Popular Tags