1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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");
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"));
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 }