001: /**********************************************************************
002: Copyright (c) 2007 Andy Jefferson 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: Contributors:
016: ...
017: **********************************************************************/package org.jpox.identity;
018:
019: import java.io.Externalizable;
020: import java.io.IOException;
021: import java.io.ObjectInput;
022: import java.io.ObjectOutput;
023:
024: import org.jpox.exceptions.JPOXException;
025: import org.jpox.exceptions.JPOXUserException;
026:
027: /**
028: * Abstract base class for all single-field identitiy classes.
029: * @version $Revision: 1.1 $
030: */
031: public abstract class SingleFieldIdentity implements Externalizable {
032: /** The class of the target object. */
033: transient private Class targetClass;
034:
035: /** The name of the class of the target object. */
036: private String targetClassName;
037:
038: /** The hashCode. */
039: protected int hashCode;
040:
041: /** The key as an Object. */
042: protected Object keyAsObject;
043:
044: /**
045: * Constructor with target class.
046: * @param pcClass the class of the target
047: */
048: protected SingleFieldIdentity(Class pcClass) {
049: if (pcClass == null)
050: throw new NullPointerException();
051: targetClass = pcClass;
052: targetClassName = pcClass.getName();
053: }
054:
055: /**
056: * Constructor only for Externalizable.
057: */
058: public SingleFieldIdentity() {
059: }
060:
061: /**
062: * Set the given key as the key for this instance. Compute the hash code for the instance.
063: */
064: protected void setKeyAsObject(Object key) {
065: assertKeyNotNull(key);
066: keyAsObject = key;
067: }
068:
069: /**
070: * Assert that the key is not null. Throw a JDONullIdentityException if the given key is null.
071: */
072: protected void assertKeyNotNull(Object key) {
073: if (key == null) {
074: throw new JPOXUserException(
075: "Cannot create SingleFieldIdentity with null parameter");
076: }
077: }
078:
079: /**
080: * Return the target class.
081: * @return the target class.
082: * @since 2.0
083: */
084: public Class getTargetClass() {
085: return targetClass;
086: }
087:
088: /**
089: * Return the target class name.
090: * @return the target class name.
091: */
092: public String getTargetClassName() {
093: return targetClassName;
094: }
095:
096: /**
097: * Return the key as an Object. The method is synchronized to avoid race conditions in multi-threaded environments.
098: * @return the key as an Object.
099: */
100: public synchronized Object getKeyAsObject() {
101: if (keyAsObject == null) {
102: keyAsObject = createKeyAsObject();
103: }
104: return keyAsObject;
105: }
106:
107: /**
108: * Create the key as an Object.
109: * @return the key as an Object;
110: */
111: protected Object createKeyAsObject() {
112: throw new JPOXException(
113: "SingleFIeldIdentity.createKeyAsObject must not be called.")
114: .setFatal();
115: }
116:
117: /**
118: * Check the class and class name and object type. If restored from serialization, class will be null so compare
119: * class name.
120: * @param obj the other object
121: * @return true if the class or class name is the same
122: */
123: public boolean equals(Object obj) {
124: if (this == obj) {
125: return true;
126: } else if (obj == null || this .getClass() != obj.getClass()) {
127: return false;
128: } else {
129: SingleFieldIdentity other = (SingleFieldIdentity) obj;
130: if (targetClass != null && targetClass == other.targetClass)
131: return true;
132: return targetClassName.equals(other.targetClassName);
133: }
134: }
135:
136: /**
137: * Return the hash code of the class name.
138: * @return the hash code of the class name
139: */
140: protected int hashClassName() {
141: return targetClassName.hashCode();
142: }
143:
144: /**
145: * Return the cached hash code.
146: * @return the cached hash code.
147: */
148: public int hashCode() {
149: return hashCode;
150: }
151:
152: /**
153: * Write to the output stream.
154: * @param out the stream
155: */
156: public void writeExternal(ObjectOutput out) throws IOException {
157: out.writeObject(targetClassName);
158: out.writeInt(hashCode);
159: }
160:
161: /**
162: * Read from the input stream. Creates a new instance with the target class name set.
163: * @param in Input
164: */
165: public void readExternal(ObjectInput in) throws IOException,
166: ClassNotFoundException {
167: targetClass = null;
168: targetClassName = (String) in.readObject();
169: hashCode = in.readInt();
170: }
171: }
|