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.IOException;
25 import java.io.ObjectInput;
26 import java.io.ObjectOutput;
27
28 import java.security.AccessController;
29 import java.security.PrivilegedAction;
30
31 import javax.jdo.JDOUserException;
32
33 import javax.jdo.spi.JDOImplHelper;
34
35 /*** This class is for identity with a single Object type field.
36 * @version 2.0
37 */
38 public class ObjectIdentity extends SingleFieldIdentity {
39
40 /*** The key is stored in the superclass field keyAsObject.
41 */
42
43 /*** The JDOImplHelper instance used for parsing the String to an Object.
44 */
45 private static JDOImplHelper helper = (JDOImplHelper)
46 AccessController.doPrivileged(
47 new PrivilegedAction () {
48 public Object run () {
49 return JDOImplHelper.getInstance();
50 }
51 }
52 );
53
54 /*** The delimiter for String constructor.
55 */
56 private static final String STRING_DELIMITER = ":";
57
58 /*** Constructor with class and key.
59 * @param pcClass the class
60 * @param param the key
61 */
62 public ObjectIdentity (Class pcClass, Object param) {
63 super (pcClass);
64 assertKeyNotNull(param);
65 String paramString = null;
66 String keyString = null;
67 String className = null;
68 if (param instanceof String) {
69
70 paramString = (String)param;
71 if (paramString.length() < 3) {
72 throw new JDOUserException(
73 msg.msg("EXC_ObjectIdentityStringConstructionTooShort") +
74 msg.msg("EXC_ObjectIdentityStringConstructionUsage",
75 paramString));
76 }
77 int indexOfDelimiter = paramString.indexOf(STRING_DELIMITER);
78 if (indexOfDelimiter < 0) {
79 throw new JDOUserException(
80 msg.msg("EXC_ObjectIdentityStringConstructionNoDelimiter") +
81 msg.msg("EXC_ObjectIdentityStringConstructionUsage",
82 paramString));
83 }
84 keyString = paramString.substring(indexOfDelimiter+1);
85 className = paramString.substring(0, indexOfDelimiter);
86 keyAsObject = helper.construct(className, keyString);
87 } else {
88 keyAsObject = param;
89 }
90 hashCode = hashClassName() ^ keyAsObject.hashCode();
91 }
92
93 /*** Constructor only for Externalizable.
94 */
95 public ObjectIdentity () {
96 }
97
98 /*** Return the key.
99 * @return the key
100 */
101 public Object getKey () {
102 return keyAsObject;
103 }
104
105 /*** Return the String form of the object id. The class of the
106 * object id is written as the first part of the result so that
107 * the class can be reconstructed later. Then the toString
108 * of the key instance is appended. During construction,
109 * this process is reversed. The class is extracted from
110 * the first part of the String, and the String constructor
111 * of the key is used to construct the key itself.
112 * @return the String form of the key
113 */
114 public String toString () {
115 return keyAsObject.getClass().getName()
116 + STRING_DELIMITER
117 + keyAsObject.toString();
118 }
119
120 /*** Determine if the other object represents the same object id.
121 * @param obj the other object
122 * @return true if both objects represent the same object id
123 */
124 public boolean equals (Object obj) {
125 if (this == obj) {
126 return true;
127 } else if (!super.equals (obj)) {
128 return false;
129 } else {
130 ObjectIdentity other = (ObjectIdentity) obj;
131 return keyAsObject.equals(other.keyAsObject);
132 }
133 }
134
135 /*** Write this object. Write the superclass first.
136 * @param out the output
137 */
138 public void writeExternal(ObjectOutput out) throws IOException {
139 super.writeExternal (out);
140 out.writeObject(keyAsObject);
141 }
142
143 /*** Read this object. Read the superclass first.
144 * @param in the input
145 */
146 public void readExternal(ObjectInput in)
147 throws IOException, ClassNotFoundException {
148 super.readExternal (in);
149 keyAsObject = in.readObject();
150 }
151
152 }