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  /*
18   * SingleFieldIdentity.java
19   *
20   */
21   
22  package javax.jdo.identity;
23  
24  import java.io.Externalizable;
25  import java.io.IOException;
26  import java.io.ObjectInput;
27  import java.io.ObjectOutput;
28  
29  import javax.jdo.JDOFatalInternalException;
30  import javax.jdo.JDONullIdentityException;
31  
32  import javax.jdo.spi.I18NHelper;
33  
34  /*** This class is the abstract base class for all single field identity
35   * classes. A common case of application identity uses exactly one 
36   * persistent field in the class to represent identity. In this case, 
37   * the application can use a standard JDO class instead of creating 
38   * a new user-defined class for the purpose.
39   * @version 2.0
40   */
41  public abstract class SingleFieldIdentity
42      implements Externalizable {
43      
44      /*** The Internationalization message helper.
45       */
46      protected static I18NHelper msg = I18NHelper.getInstance ("javax.jdo.Bundle"); //NOI18N
47  
48      /*** The class of the target object.
49       */
50      transient private Class targetClass;
51      
52      /*** The name of the class of the target object.
53       */
54      private String targetClassName;
55  
56      /*** The hashCode.
57       */
58      protected int hashCode;
59      
60      /*** The key as an Object.
61       */
62      protected Object keyAsObject;
63  
64      /*** Constructor with target class.
65       * @param pcClass the class of the target
66       * @since 2.0
67       */
68      protected SingleFieldIdentity(Class pcClass) {
69          if (pcClass == null)
70              throw new NullPointerException();
71          targetClass = pcClass;
72          targetClassName = pcClass.getName();
73      }
74  
75      /*** Constructor only for Externalizable.
76       * @since 2.0
77       */
78      public SingleFieldIdentity () {
79      }
80  
81      /*** Set the given key as the key for this instance. 
82       * Compute the hash code for the instance.
83       * @since 2.0
84       */
85      protected void setKeyAsObject(Object key) {
86          assertKeyNotNull(key);
87          keyAsObject = key;
88      }
89  
90      /*** Assert that the key is not null. Throw a JDONullIdentityException
91       * if the given key is null.
92       * @since 2.0
93       */ 
94      protected void assertKeyNotNull(Object key) {
95          if (key == null) {
96              throw new JDONullIdentityException(
97                  msg.msg("EXC_SingleFieldIdentityNullParameter")); //NOI18N
98          }
99      }
100     
101     /*** Return the target class.
102      * @return the target class.
103      * @since 2.0
104      */
105     public Class getTargetClass() {
106         return targetClass;
107     }
108 
109     /*** Return the target class name.
110      * @return the target class name.
111      * @since 2.0
112      */
113     public String getTargetClassName() {
114         return targetClassName;
115     }
116 
117     /*** Return the key as an Object. The method is synchronized to avoid
118      * race conditions in multi-threaded environments.
119      * @return the key as an Object.
120      * @since 2.0
121      */
122     public synchronized Object getKeyAsObject() {
123         if (keyAsObject == null) {
124             keyAsObject = createKeyAsObject();
125         }
126         return keyAsObject;
127     }
128     
129     /*** Create the key as an Object.
130      * @return the key as an Object;
131      * @since 2.0
132      */
133     protected Object createKeyAsObject() {
134         throw new JDOFatalInternalException
135                 (msg.msg("EXC_CreateKeyAsObjectMustNotBeCalled"));
136     }
137     
138     /*** Check the class and class name and object type. If restored
139      * from serialization, class will be null so compare class name.
140      * @param obj the other object
141      * @return true if the class or class name is the same
142      */
143     public boolean equals(Object obj) {
144         if (this == obj) {
145             return true;
146         } else if (obj == null || this.getClass() != obj.getClass()) {
147             return false;
148         } else {
149             SingleFieldIdentity other = (SingleFieldIdentity) obj;
150             if (targetClass != null && targetClass == other.targetClass)
151                 return true;
152             return targetClassName.equals (other.targetClassName);
153         }
154     }
155 
156     /*** Return the hash code of the class name.
157      * @return the hash code of the class name
158      * @since 2.0
159      */
160     protected int hashClassName() {
161         return targetClassName.hashCode();
162     }
163     
164     /*** Return the cached hash code.
165      * @return the cached hash code.
166      */
167     public int hashCode() {
168         return hashCode;
169     }
170     
171     /*** Write to the output stream.
172      * @param out the stream
173      */
174     public void writeExternal(ObjectOutput out) throws IOException {
175         out.writeObject(targetClassName);
176         out.writeInt(hashCode);
177     }
178 
179     /*** Read from the input stream.
180      * Creates a new instance with the target class name set
181      */
182     public void readExternal(ObjectInput in)
183             throws IOException, ClassNotFoundException {
184         targetClass = null;
185         targetClassName = (String)in.readObject();
186         hashCode = in.readInt();
187     }
188 }