001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.common;
012:
013: import com.versant.core.metadata.ClassMetaData;
014: import com.versant.core.util.OIDObjectInput;
015: import com.versant.core.util.OIDObjectOutput;
016:
017: import java.io.*;
018:
019: /**
020: * This OID class is used for new JDO instances of any type. It is used as
021: * a placeholder for the real OID for new objects. The realOID field is
022: * filled once the real OID has been created so that references to this
023: * OID can be fixed up.
024: */
025: public class NewObjectOID implements OID {
026:
027: private ClassMetaData cmd;
028: /**
029: * This is an id that has to be unique in a client space.
030: *
031: * @see #init
032: */
033: public int idNo;
034: /**
035: * The real OID generated for this object. This is filled when the new
036: * object is persisted. Other objects with references to this OID use
037: * this field instead when they are persisted.
038: */
039: public OID realOID;
040:
041: public NewObjectOID(ClassMetaData cmd) {
042: this .cmd = cmd;
043: }
044:
045: /**
046: * This is only for used for Externalizable
047: *
048: * @see java.io.Externalizable
049: */
050: public NewObjectOID() {
051: }
052:
053: /**
054: * Is this an OID for a new object?
055: */
056: public boolean isNew() {
057: return true;
058: }
059:
060: public boolean isResolved() {
061: return true;
062: }
063:
064: public void resolve(State state) {
065: }
066:
067: public int getIdentityType() {
068: return cmd.identityType;
069: }
070:
071: /**
072: * Initialise the oid.
073: */
074: public void init(int id) {
075: idNo = id;
076: }
077:
078: public int getClassIndex() {
079: return cmd.index;
080: }
081:
082: public ClassMetaData getCmd() {
083: return cmd;
084: }
085:
086: /**
087: * Get the meta data for our class.
088: *
089: */
090: public ClassMetaData getClassMetaData() {
091: return cmd;
092: }
093:
094: public ClassMetaData getAvailableClassMetaData() {
095: return cmd;
096: }
097:
098: public ClassMetaData getBaseClassMetaData() {
099: return cmd.top;
100: }
101:
102: public void copyKeyFields(Object[] data) {
103: throw BindingSupportImpl.getInstance().internal(
104: "copyKeyFields(Object[]) called on NewObjectOID");
105: }
106:
107: public OID copy() {
108: NewObjectOID nOID = new NewObjectOID();
109: nOID.cmd = cmd;
110: nOID.idNo = idNo;
111: return nOID;
112: }
113:
114: public void fillFromPK(Object pk) {
115: //no-op
116: }
117:
118: public OID fillFromIDObject(Object id) {
119: //no-op
120: return this ;
121: }
122:
123: public int hashCode() {
124: return cmd.index + idNo;
125: }
126:
127: public boolean equals(Object obj) {
128: if (obj == this )
129: return true;
130: if (obj instanceof NewObjectOID) {
131: NewObjectOID other = (NewObjectOID) obj;
132: if (other.cmd == cmd && other.idNo == idNo) {
133: return true;
134: }
135: }
136: return false;
137: }
138:
139: public String toString() {
140: return toStringImp();
141: }
142:
143: /**
144: * Get the toString of this OID even if it has not been resolved.
145: */
146: public String toStringImp() {
147: return "NewObjectOID@"
148: + Integer.toHexString(System.identityHashCode(this ))
149: + " classIndex = " + cmd.index + " id = " + idNo
150: + " realOID = " + realOID;
151: }
152:
153: public String toSString() {
154: return "NewObjectOID@"
155: + Integer.toHexString(System.identityHashCode(this ))
156: + " classIndex = "
157: + cmd.index
158: + " id = "
159: + idNo
160: + (realOID == null ? "" : " realOID = "
161: + realOID.toSString());
162: }
163:
164: public String toPkString() {
165: return "(New)";
166: }
167:
168: public OID getAvailableOID() {
169: if (realOID != null)
170: return realOID;
171: return this ;
172: }
173:
174: public OID getRealOID() {
175: return realOID;
176: }
177:
178: public OID setRealOid(OID oid) {
179: if (oid == null) {
180: throw BindingSupportImpl.getInstance().internal(
181: "The supplied oid is NULL");
182: }
183: if (this .realOID == null) {
184: this .realOID = oid;
185: } else {
186: if (!this .realOID.equals(oid)) {
187: throw BindingSupportImpl.getInstance().internal(
188: "The supplied R-OID is not "
189: + "equal to the current realOID");
190: }
191: }
192: return oid;
193: }
194:
195: public void writeExternal(OIDObjectOutput os) throws IOException {
196: os.writeInt(idNo);
197: os.write(realOID);
198: }
199:
200: public void readExternal(OIDObjectInput is)
201: throws ClassNotFoundException, IOException {
202: idNo = is.readInt();
203: realOID = is.readOID();
204: }
205:
206: public void fillFromIDString(String idString, int index) {
207: throw BindingSupportImpl.getInstance().internal(
208: "fillFromIDString called");
209: }
210:
211: public void fillFromIDString(String idString) {
212: throw BindingSupportImpl.getInstance().internal(
213: "Should not be called");
214: }
215:
216: public int compareTo(Object o) {
217: OID oo = (OID) o;
218: int diff = cmd.index - oo.getClassIndex();
219: if (diff != 0)
220: return diff;
221: if (oo.isNew()) {
222: return idNo - ((NewObjectOID) o).idNo;
223: } else {
224: return -1; // we are always before non-new OIDs
225: }
226: }
227:
228: /**
229: * Return the primary key stored in this OID as an long. This will only
230: * be called for datastore identity classes.
231: */
232: public long getLongPrimaryKey() {
233: if (realOID == null)
234: return idNo;
235: return realOID.getLongPrimaryKey();
236: }
237:
238: /**
239: * Set the primary key stored in this OID as an long. This will only be
240: * called for datastore identity classes.
241: */
242: public void setLongPrimaryKey(long pk) {
243: realOID.setLongPrimaryKey(pk);
244: }
245:
246: public void populateObjectIdClassInstance(Object o) {
247: throw BindingSupportImpl.getInstance().internal(
248: "Should not be called");
249: }
250:
251: public int getAvailableClassId() {
252: return getAvailableClassMetaData().classId;
253: }
254:
255: public NewObjectOID newInstance(ClassMetaData cmd) {
256: return new NewObjectOID(cmd);
257: }
258:
259: }
|