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   * ObjectIdentity.java
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 = ":"; //NOI18N
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              /* The paramString is of the form "<className>:<keyString>" */
70              paramString = (String)param;
71              if (paramString.length() < 3) {
72                  throw new JDOUserException(
73                      msg.msg("EXC_ObjectIdentityStringConstructionTooShort") + //NOI18N
74                      msg.msg("EXC_ObjectIdentityStringConstructionUsage", //NOI18N
75                          paramString));
76              }
77              int indexOfDelimiter = paramString.indexOf(STRING_DELIMITER);
78              if (indexOfDelimiter < 0) {
79                  throw new JDOUserException(
80                      msg.msg("EXC_ObjectIdentityStringConstructionNoDelimiter") + //NOI18N
81                      msg.msg("EXC_ObjectIdentityStringConstructionUsage", //NOI18N
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 }