View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at 
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  
17  package org.apache.jdo.impl.model.jdo.caching;
18  
19  import org.apache.jdo.model.ModelException;
20  import org.apache.jdo.model.java.JavaField;
21  import org.apache.jdo.model.jdo.JDOArray;
22  import org.apache.jdo.model.jdo.JDOClass;
23  import org.apache.jdo.model.jdo.JDOCollection;
24  import org.apache.jdo.model.jdo.JDOMap;
25  import org.apache.jdo.model.jdo.JDOReference;
26  import org.apache.jdo.model.jdo.JDORelationship;
27  import org.apache.jdo.model.jdo.PersistenceModifier;
28  import org.apache.jdo.impl.model.jdo.JDOFieldImplDynamic;
29  
30  /***
31   * An instance of this class represents the JDO metadata of a managed
32   * field of a persistence capable class. This caching implementation
33   * caches any calulated value to avoid re-calculating it if it is
34   * requested again. 
35   * <p>
36   * Please note, this implementation does not support
37   * changing the relationship property once it is defined (either
38   * explicitly by the setter or internally calculated by the
39   * getter). The second attempt to define the relationship will result
40   * in an exception.
41   *
42   * @author Michael Bouschen
43   * @since 1.1
44   * @version 2.0
45   */
46  public class JDOFieldImplCaching extends JDOFieldImplDynamic {
47  
48      /*** Relative field number. */
49      private int relativeFieldNumber = -1;
50  
51      /*** Constructor. */
52      protected JDOFieldImplCaching(String name, JDOClass declaringClass) {
53          super(name, declaringClass);
54      }
55  
56      /***
57       * Get the persistence modifier of this JDOField.
58       * @return the persistence modifier, one of 
59       * {@link PersistenceModifier#NONE}, 
60       * {@link PersistenceModifier#PERSISTENT},
61       * {@link PersistenceModifier#TRANSACTIONAL}, or
62       * {@link PersistenceModifier#POSSIBLY_PERSISTENT}.
63       */
64      public int getPersistenceModifier() {
65          if (persistenceModifier == PersistenceModifier.UNSPECIFIED) {
66              persistenceModifier = super.getPersistenceModifier();
67          }
68          return persistenceModifier;
69      }
70  
71      /***
72       * Returns the relative field number of this JDOField.
73       * @return the relative field number
74       */
75      public int getRelativeFieldNumber() {
76          ((JDOClassImplCaching)getDeclaringClass()).calculateFieldNumbers();
77          return relativeFieldNumber;
78      }
79  
80      /***
81       * Determines whether this JDOField is part of the default fetch group or 
82       * not.
83       * @return <code>true</code> if the field is part of the default fetch 
84       * group, <code>false</code> otherwise
85       */
86      public boolean isDefaultFetchGroup() {
87          if (defaultFetchGroup == null) {
88              defaultFetchGroup = 
89                  super.isDefaultFetchGroup() ? Boolean.TRUE : Boolean.FALSE;
90          }
91          return (defaultFetchGroup == null) ? 
92              false : defaultFetchGroup.booleanValue();
93      }
94  
95      /***
96       * Determines whether the field should be stored if possible as part of
97       * the instance instead of as its own instance in the datastore.
98       * @return <code>true</code> if the field is stored as part of the instance;
99       * <code>false</code> otherwise
100      */
101     public boolean isEmbedded() {
102         if (embedded == null) {
103             embedded = super.isEmbedded() ? Boolean.TRUE : Boolean.FALSE;
104         }
105         return (embedded == null) ? false : embedded.booleanValue();
106     }
107     
108     /***
109      * Get the corresponding JavaField representation for this JDOField.
110      * @return the corresponding Java field representation
111      */
112     public JavaField getJavaField() {
113         if (javaField == null) {
114             javaField = super.getJavaField();
115         }
116         return javaField;
117     }
118 
119     /***
120      * Get the relationship information for this JDOField. The method 
121      * returns null if the field is not part of a relationship 
122      * (e.g. it is a primitive type field).
123      * @return relationship info of this JDOField or <code>null</code> if 
124      * this JDOField is not a relationship
125      */
126     public JDORelationship getRelationship() {
127         if (relationship == null) {
128             relationship = super.getRelationship();
129         }
130         return relationship;
131     }
132     
133     /***
134      * Creates and returns a new JDOReference instance. 
135      * This method automatically binds the new JDOReference to this JDOField. 
136      * It throws a ModelException, if this JDOField is already bound to 
137      * another JDORelationship instance. Otherwise the following holds true:
138      * <ul>
139      * <li> Method {@link #getRelationship} returns the new created instance
140      * <li> <code>this.getRelationship().getDeclaringField() == this</code>
141      * </ul> 
142      * @return a new JDOReference instance bound to this JDOField
143      * @exception ModelException if impossible
144      */
145     public JDOReference createJDOReference() throws ModelException {
146         if (relationship != null)
147             throw new ModelException(
148                 msg.msg("EXC_RelationshipAlreadyDefined", //NOI18N
149                         getName(), relationship));
150         return super.createJDOReference();
151     }
152 
153     /***
154      * Creates and returns a new JDOCollection instance. 
155      * This method automatically binds the new JDOCollection to this JDOField. 
156      * It throws a ModelException, if this JDOField is already bound to 
157      * another JDORelationship instance. Otherwise the following holds true:
158      * <ul>
159      * <li> Method {@link #getRelationship} returns the new created instance
160      * <li> <code>this.getRelationship().getDeclaringField() == this</code>
161      * </ul> 
162      * @return a new JDOCollection instance bound to this JDOField
163      * @exception ModelException if impossible
164      */
165     public JDOCollection createJDOCollection() throws ModelException {
166         if (relationship != null)
167             throw new ModelException(
168                 msg.msg("EXC_RelationshipAlreadyDefined", //NOI18N
169                         getName(), relationship));
170         return super.createJDOCollection();
171     }
172 
173     /***
174      * Creates and returns a new JDOArray instance. 
175      * This method automatically binds the new JDOArray to this JDOField. 
176      * It throws a ModelException, if this JDOField is already bound to 
177      * another JDORelationship instance. Otherwise the following holds true:
178      * <ul>
179      * <li> Method {@link #getRelationship} returns the new created instance
180      * <li> <code>this.getRelationship().getDeclaringField() == this</code>
181      * </ul> 
182      * @return a new JDOArray instance bound to this JDOField
183      * @exception ModelException if impossible
184      */
185     public JDOArray createJDOArray() throws ModelException {
186         if (relationship != null)
187             throw new ModelException(
188                 msg.msg("EXC_RelationshipAlreadyDefined", //NOI18N
189                         getName(), relationship));
190         return super.createJDOArray();
191     }
192 
193     /***
194      * Creates and returns a new JDOMap instance. 
195      * This method automatically binds the new JDOMap to this JDOField. 
196      * It throws a ModelException, if this JDOField is already bound to 
197      * another JDORelationship instance. Otherwise the following holds true:
198      * <ul>
199      * <li> Method {@link #getRelationship} returns the new created instance
200      * <li> <code>this.getRelationship().getDeclaringField() == this</code>
201      * </ul> 
202      * @return a new JDOMap instance bound to this JDOField
203      * @exception ModelException if impossible
204      */
205     public JDOMap createJDOMap() throws ModelException {
206         if (relationship != null)
207             throw new ModelException(
208                 msg.msg("EXC_RelationshipAlreadyDefined", //NOI18N
209                         getName(), relationship));
210         return super.createJDOMap();
211     }
212 
213     //========= Internal helper methods ==========
214 
215     /***
216      * Creates and returns a new JDOReference instance. 
217      * This method automatically sets this JDOField as the declaring field of 
218      * the returned instance.
219      * @return a new JDOReference instance bound to this JDOField
220      */
221     protected JDOReference createJDOReferenceInternal() {
222         JDOReferenceImplCaching ref = new JDOReferenceImplCaching();
223         // update relationship JDORelationship->JDOField
224         ref.setDeclaringField(this);
225         return ref;
226     }
227 
228     /***
229      * Creates and returns a new JDOCollection instance. 
230      * This method automatically this JDOField as the declarinmg field of 
231      * the returned instance.
232      * @return a new JDOCollection instance bound to this JDOField
233      */
234     protected JDOCollection createJDOCollectionInternal() {
235         JDOCollectionImplCaching collection = new JDOCollectionImplCaching();
236         // update relationship JDORelationship->JDOField
237         collection.setDeclaringField(this);
238         return collection;
239     }
240 
241     /***
242      * Creates and returns a new JDOArray instance. 
243      * This method automatically this JDOField as the declarinmg field of 
244      * the returned instance.
245      * @return a new JDOArray instance bound to this JDOField
246      */
247     protected JDOArray createJDOArrayInternal() {
248         JDOArrayImplCaching array = new JDOArrayImplCaching();
249         // update relationship JDORelationship->JDOField
250         array.setDeclaringField(this);
251         return array;
252     }
253 
254     /***
255      * Creates and returns a new JDOMap instance. 
256      * This method automatically this JDOField as the declarinmg field of 
257      * the returned instance.
258      * @return a new JDOMap instance bound to this JDOField
259      */
260     protected JDOMap createJDOMapInternal() {
261         JDOMapImplCaching map = new JDOMapImplCaching();
262         // update relationship JDORelationship->JDOField
263         map.setDeclaringField(this);
264         return map;
265     }
266 
267     /***
268      * Sets the relative field number of this JDOField.
269      * @param number the relative field number
270      */
271     void setRelativeFieldNumber(int number) {
272         this.relativeFieldNumber = number;
273     }
274 }