View Javadoc

1   /**********************************************************************
2    Copyright (c) 2002 Kelly Grizzle (TJDO) and others. All rights reserved.
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6   
7    http://www.apache.org/licenses/LICENSE-2.0
8   
9    Unless required by applicable law or agreed to in writing, software
10   distributed under the License is distributed on an "AS IS" BASIS,
11   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   See the License for the specific language governing permissions and
13   limitations under the License.
14  
15  
16   Contributors:
17   2003 Erik Bengtson - Refactored OID
18   2003 Andy Jefferson - fixed OID(String)
19   2003 Andy Jefferson - coding standards
20   2004 Andy Jefferson - fixes to allow full use of long or String OIDs
21   2005 Erik Bengtson - removed oidType
22   2007 Brett Porter - changed hashcode algorithm to avoid collisions (see CORE-3297)
23   ...
24   **********************************************************************/
25  package org.jpox.store;
26  
27  import org.jpox.ClassNameConstants;
28  import org.jpox.util.Localiser;
29  
30  /**
31   * An object identifier. OIDs are normally used as object identifiers for
32   * persistent objects that use datastore identity. They're also used for
33   * view objects, which actually use non-datastore identity. The behaviour of
34   * this class is governed by JDO spec 5.4.3.
35   *
36   * @version $Revision: 1.17 $
37   */
38  public class OID
39      implements java.io.Serializable
40  {
41      private transient static final Localiser LOCALISER = Localiser.getInstance( "org.jpox.store.Localisation" );
42  
43      /**
44       * Separator to use between fields.
45       */
46      private transient static final String oidSeparator = "[OID]";
47  
48      // JDO spec 5.4.3 - serializable fields required to be public.
49  
50      /**
51       * The identity.
52       */
53      public final Object oid;
54  
55      /**
56       * The PersistenceCapable class name
57       */
58      public final String pcClass;
59  
60      /**
61       * pre-created toString to improve performance *
62       */
63      public final String toString;
64  
65      /**
66       * pre-created hasCode to improve performance *
67       */
68      public final int hashCode;
69  
70      /**
71       * Creates an OID with the no value.
72       * Required by the JDO spec
73       */
74      public OID()
75      {
76          oid = null;
77          pcClass = null;
78          toString = null;
79          hashCode = -1;
80      }
81  
82      /**
83       * Create a string datastore identity
84       *
85       * @param pcClass The PersistenceCapable class that this represents
86       * @param object  The value
87       */
88      public OID( String pcClass, Object object )
89      {
90          this.pcClass = pcClass;
91          this.oid = object;
92  
93          StringBuffer s = new StringBuffer();
94          s.append( this.oid.toString() );
95          s.append( oidSeparator );
96          s.append( this.pcClass );
97          toString = s.toString();
98          hashCode = this.oid.hashCode() * 39 + pcClass.hashCode();
99      }
100 
101     /**
102      * Constructs an OID from its string representation that is
103      * consistent with the output of toString().
104      *
105      * @param str the string representation of an OID.
106      * @throws IllegalArgumentException if the given string representation is not valid.
107      * @see #toString
108      */
109     public OID( String str )
110         throws IllegalArgumentException
111     {
112         if ( str.length() < 2 )
113         {
114             throw new IllegalArgumentException( LOCALISER.msg( "OID.InvalidValue", str ) );
115         }
116 
117         int start = 0;
118         int end = str.indexOf( oidSeparator, start );
119         String oidStr = str.substring( start, end );
120         Object oidValue = null;
121         try
122         {
123             // Use Long if possible, else String
124             oidValue = new Long( oidStr );
125         }
126         catch ( NumberFormatException nfe )
127         {
128             oidValue = oidStr;
129         }
130         oid = oidValue;
131 
132         start = end + oidSeparator.length();
133         this.pcClass = str.substring( start, str.length() );
134 
135         toString = str;
136         hashCode = this.oid.hashCode() * 39 + pcClass.hashCode();
137     }
138 
139     /**
140      * Returns copy of the requested oid to be accessed by the user.
141      *
142      * @return Copy of the OID.
143      */
144     public Object getNewObjectIdCopy()
145     {
146         return new OID( this.pcClass, this.oid );
147     }
148 
149     /**
150      * Provides the OID in a form that can be used by the database as a key.
151      *
152      * @return The key value
153      */
154     public Object keyValue()
155     {
156         return oid;
157     }
158 
159     /**
160      * Equality operator.
161      *
162      * @param obj Object to compare against
163      * @return Whether they are equal
164      */
165     public boolean equals( Object obj )
166     {
167         if ( obj == null )
168         {
169             return false;
170         }
171         if ( obj == this )
172         {
173             return true;
174         }
175         if ( !( obj.getClass().getName().equals( ClassNameConstants.OID ) ) )
176         {
177             return false;
178         }
179         if ( hashCode() != obj.hashCode() )
180         {
181             return false;
182         }
183         return true;
184     }
185 
186     /**
187      * Accessor for the hashcode
188      *
189      * @return Hashcode for this object
190      */
191     public int hashCode()
192     {
193         return hashCode;
194     }
195 
196     /**
197      * Returns the string representation of the OID.
198      * Will be a string such as "1[OID]org.jpox.samples.MyClass"
199      * where
200      * <UL>
201      * <LI>1 is the identity "id"</LI>
202      * <LI>class name is the name of the PersistenceCapable class that it represents</LI>
203      * </UL>
204      *
205      * @return the string representation of the OID.
206      */
207     public String toString()
208     {
209         return toString;
210     }
211 
212     /**
213      * Accessor for the PC class name
214      *
215      * @return the PC Class
216      */
217     public String getPcClass()
218     {
219         return pcClass;
220     }
221 }