1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package javax.jdo.identity;
24
25 import java.io.IOException;
26 import java.io.ObjectInput;
27 import java.io.ObjectOutput;
28
29 import java.security.AccessController;
30 import java.security.PrivilegedAction;
31
32 import javax.jdo.JDOUserException;
33
34 import javax.jdo.spi.JDOImplHelper;
35
36 /*** This class is for identity with a single Object type field.
37 * @version 2.0
38 */
39 public class ObjectIdentity extends SingleFieldIdentity {
40
41 /*** The key is stored in the superclass field keyAsObject.
42 */
43
44 /*** The JDOImplHelper instance used for parsing the String to an Object.
45 */
46 private static JDOImplHelper helper = (JDOImplHelper)
47 AccessController.doPrivileged(
48 new PrivilegedAction () {
49 public Object run () {
50 return JDOImplHelper.getInstance();
51 }
52 }
53 );
54
55 /*** The delimiter for String constructor.
56 */
57 private static final String STRING_DELIMITER = ":";
58
59 /*** Constructor with class and key.
60 * @param pcClass the class
61 * @param param the key
62 */
63 public ObjectIdentity (Class pcClass, Object param) {
64 super (pcClass);
65 assertKeyNotNull(param);
66 String paramString = null;
67 String keyString = null;
68 String className = null;
69 if (param instanceof String) {
70
71 paramString = (String)param;
72 if (paramString.length() < 3) {
73 throw new JDOUserException(
74 msg.msg("EXC_ObjectIdentityStringConstructionTooShort") +
75 msg.msg("EXC_ObjectIdentityStringConstructionUsage",
76 paramString));
77 }
78 int indexOfDelimiter = paramString.indexOf(STRING_DELIMITER);
79 if (indexOfDelimiter < 0) {
80 throw new JDOUserException(
81 msg.msg("EXC_ObjectIdentityStringConstructionNoDelimiter") +
82 msg.msg("EXC_ObjectIdentityStringConstructionUsage",
83 paramString));
84 }
85 keyString = paramString.substring(indexOfDelimiter+1);
86 className = paramString.substring(0, indexOfDelimiter);
87 keyAsObject = helper.construct(className, keyString);
88 } else {
89 keyAsObject = param;
90 }
91 hashCode = hashClassName() ^ keyAsObject.hashCode();
92 }
93
94 /*** Constructor only for Externalizable.
95 */
96 public ObjectIdentity () {
97 }
98
99 /*** Return the key.
100 * @return the key
101 */
102 public Object getKey () {
103 return keyAsObject;
104 }
105
106 /*** Return the String form of the object id. The class of the
107 * object id is written as the first part of the result so that
108 * the class can be reconstructed later. Then the toString
109 * of the key instance is appended. During construction,
110 * this process is reversed. The class is extracted from
111 * the first part of the String, and the String constructor
112 * of the key is used to construct the key itself.
113 * @return the String form of the key
114 */
115 public String toString () {
116 return keyAsObject.getClass().getName()
117 + STRING_DELIMITER
118 + keyAsObject.toString();
119 }
120
121 /*** Determine if the other object represents the same object id.
122 * @param obj the other object
123 * @return true if both objects represent the same object id
124 */
125 public boolean equals (Object obj) {
126 if (this == obj) {
127 return true;
128 } else if (!super.equals (obj)) {
129 return false;
130 } else {
131 ObjectIdentity other = (ObjectIdentity) obj;
132 return keyAsObject.equals(other.keyAsObject);
133 }
134 }
135
136 /*** Determine the ordering of identity objects.
137 * @param o Other identity
138 * @return The relative ordering between the objects
139 * @since 2.2
140 */
141 public int compareTo(Object o) {
142 if (o instanceof ObjectIdentity) {
143 ObjectIdentity other = (ObjectIdentity)o;
144 int result = super.compare(other);
145 if (result == 0) {
146 if (other.keyAsObject instanceof Comparable &&
147 keyAsObject instanceof Comparable) {
148 return ((Comparable)keyAsObject).compareTo(
149 (Comparable)other.keyAsObject);
150 }
151 else
152 {
153 throw new ClassCastException("The key class (" +
154 keyAsObject.getClass().getName() +
155 ") does not implement Comparable");
156 }
157 } else {
158 return result;
159 }
160 }
161 else if (o == null) {
162 throw new ClassCastException("object is null");
163 }
164 throw new ClassCastException(this.getClass().getName() +
165 " != " + o.getClass().getName());
166 }
167
168 /*** Write this object. Write the superclass first.
169 * @param out the output
170 */
171 public void writeExternal(ObjectOutput out) throws IOException {
172 super.writeExternal (out);
173 out.writeObject(keyAsObject);
174 }
175
176 /*** Read this object. Read the superclass first.
177 * @param in the input
178 */
179 public void readExternal(ObjectInput in)
180 throws IOException, ClassNotFoundException {
181 super.readExternal (in);
182 keyAsObject = in.readObject();
183 }
184
185 }