001: /**********************************************************************
002: Copyright (c) 2002 Kelly Grizzle (TJDO) and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: 2003 Erik Bengtson - Refactored OID
018: 2003 Andy Jefferson - fixed OID(String)
019: 2003 Andy Jefferson - coding standards
020: 2004 Andy Jefferson - fixes to allow full use of long or String OIDs
021: 2005 Erik Bengtson - removed oidType
022: ...
023: **********************************************************************/package org.jpox.identity;
024:
025: import org.jpox.ClassNameConstants;
026: import org.jpox.util.Localiser;
027:
028: /**
029: * An object identifier. OIDs are normally used as object identifiers for persistent objects that use datastore identity.
030: * They're also used for view objects, which actually use non-datastore identity.
031: * The behaviour of this class is governed by JDO spec 5.4.3.
032: * Utilises a String form of the style "3258[OID]mydomain.MyClass".
033: *
034: * @version $Revision: 1.2 $
035: */
036: public class OIDImpl implements java.io.Serializable, OID {
037: /** Localiser for messages. */
038: protected static final transient Localiser LOCALISER = Localiser
039: .getInstance("org.jpox.store.Localisation");
040:
041: /** Separator to use between fields. */
042: private transient static final String oidSeparator = "[OID]";
043:
044: // JDO spec 5.4.3 says: all serializable fields of ObjectID classes are required to be public.
045:
046: /** The key value. */
047: public final Object oid;
048:
049: /** The PersistenceCapable class name */
050: public final String pcClass;
051:
052: /** pre-created toString to improve performance **/
053: public final String toString;
054:
055: /** pre-created hasCode to improve performance **/
056: public final int hashCode;
057:
058: /**
059: * Creates an OID with no value. Required by the JDO spec
060: */
061: public OIDImpl() {
062: oid = null;
063: pcClass = null;
064: toString = null;
065: hashCode = -1;
066: }
067:
068: /**
069: * Create a string datastore identity.
070: * @param pcClass The PersistenceCapable class that this represents
071: * @param object The value
072: */
073: public OIDImpl(String pcClass, Object object) {
074: this .pcClass = pcClass;
075: this .oid = object;
076:
077: StringBuffer s = new StringBuffer();
078: s.append(this .oid.toString());
079: s.append(oidSeparator);
080: s.append(this .pcClass);
081: toString = s.toString();
082: hashCode = toString.hashCode();
083: }
084:
085: /**
086: * Constructs an OID from its string representation that is consistent with the output of toString().
087: * @param str the string representation of an OID
088: * @exception IllegalArgumentException if the given string representation is not valid.
089: * @see #toString
090: */
091: public OIDImpl(String str) throws IllegalArgumentException {
092: if (str.length() < 2) {
093: throw new IllegalArgumentException(LOCALISER.msg("038000",
094: str));
095: }
096:
097: int start = 0;
098: int end = str.indexOf(oidSeparator, start);
099: String oidStr = str.substring(start, end);
100: Object oidValue = null;
101: try {
102: // Use Long if possible, else String
103: oidValue = new Long(oidStr);
104: } catch (NumberFormatException nfe) {
105: oidValue = oidStr;
106: }
107: oid = oidValue;
108:
109: start = end + oidSeparator.length();
110: this .pcClass = str.substring(start, str.length());
111:
112: toString = str;
113: hashCode = toString.hashCode();
114: }
115:
116: /**
117: * Accessor for the key value.
118: * @return The key value
119: */
120: public Object getKeyValue() {
121: return oid;
122: }
123:
124: /**
125: * Accessor for the PersistenceCapable class name.
126: * @return PC class name
127: */
128: public String getPcClass() {
129: return pcClass;
130: }
131:
132: /**
133: * Equality operator.
134: * @param obj Object to compare against
135: * @return Whether they are equal
136: */
137: public boolean equals(Object obj) {
138: if (obj == null) {
139: return false;
140: }
141: if (obj == this ) {
142: return true;
143: }
144: if (!(obj.getClass().getName()
145: .equals(ClassNameConstants.OIDImpl))) {
146: return false;
147: }
148: if (hashCode() != obj.hashCode()) {
149: return false;
150: }
151: if (!((OID) obj).toString().equals(toString)) {
152: // Hashcodes are the same but the values aren't
153: return false;
154: }
155: return true;
156: }
157:
158: /**
159: * Accessor for the hashcode
160: * @return Hashcode for this object
161: */
162: public int hashCode() {
163: return hashCode;
164: }
165:
166: /**
167: * Creates a String representation of the datastore identity, formed from the PC class name
168: * and the key value. This will be something like
169: * <pre>3254[OID]mydomain.MyClass</pre>
170: * @return The String form of the identity
171: */
172: public String toString() {
173: return toString;
174: }
175: }
|