blob: 77056a2fb9db4bb2b5a00bf5dcc71099ea1ec25e [file] [log] [blame]
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* SingleFieldIdentity.java
*
*/
package javax.jdo.identity;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.jdo.JDOFatalInternalException;
import javax.jdo.JDONullIdentityException;
import javax.jdo.spi.I18NHelper;
/** This class is the abstract base class for all single field identity
* classes. A common case of application identity uses exactly one
* persistent field in the class to represent identity. In this case,
* the application can use a standard JDO class instead of creating
* a new user-defined class for the purpose.
* @version 2.0
*/
public abstract class SingleFieldIdentity
implements Externalizable {
/** The Internationalization message helper.
*/
protected static I18NHelper msg = I18NHelper.getInstance ("javax.jdo.Bundle"); //NOI18N
/** The class of the target object.
*/
transient private Class targetClass;
/** The name of the class of the target object.
*/
private String targetClassName;
/** The hashCode.
*/
protected int hashCode;
/** The key as an Object.
*/
protected Object keyAsObject;
/** Constructor with target class.
* @param pcClass the class of the target
* @since 2.0
*/
protected SingleFieldIdentity(Class pcClass) {
if (pcClass == null)
throw new NullPointerException();
targetClass = pcClass;
targetClassName = pcClass.getName();
}
/** Constructor only for Externalizable.
* @since 2.0
*/
public SingleFieldIdentity () {
}
/** Set the given key as the key for this instance.
* Compute the hash code for the instance.
* @since 2.0
*/
protected void setKeyAsObject(Object key) {
assertKeyNotNull(key);
keyAsObject = key;
}
/** Assert that the key is not null. Throw a JDONullIdentityException
* if the given key is null.
* @since 2.0
*/
protected void assertKeyNotNull(Object key) {
if (key == null) {
throw new JDONullIdentityException(
msg.msg("EXC_SingleFieldIdentityNullParameter")); //NOI18N
}
}
/** Return the target class.
* @return the target class.
* @since 2.0
*/
public Class getTargetClass() {
return targetClass;
}
/** Return the target class name.
* @return the target class name.
* @since 2.0
*/
public String getTargetClassName() {
return targetClassName;
}
/** Return the key as an Object. The method is synchronized to avoid
* race conditions in multi-threaded environments.
* @return the key as an Object.
* @since 2.0
*/
public synchronized Object getKeyAsObject() {
if (keyAsObject == null) {
keyAsObject = createKeyAsObject();
}
return keyAsObject;
}
/** Create the key as an Object.
* @return the key as an Object;
* @since 2.0
*/
protected Object createKeyAsObject() {
throw new JDOFatalInternalException
(msg.msg("EXC_CreateKeyAsObjectMustNotBeCalled"));
}
/** Check the class and class name and object type. If restored
* from serialization, class will be null so compare class name.
* @param obj the other object
* @return true if the class or class name is the same
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj == null || this.getClass() != obj.getClass()) {
return false;
} else {
SingleFieldIdentity other = (SingleFieldIdentity) obj;
if (targetClass != null && targetClass == other.targetClass)
return true;
return targetClassName.equals (other.targetClassName);
}
}
/** Return the hash code of the class name.
* @return the hash code of the class name
* @since 2.0
*/
protected int hashClassName() {
return targetClassName.hashCode();
}
/** Return the cached hash code.
* @return the cached hash code.
*/
public int hashCode() {
return hashCode;
}
/** Write to the output stream.
* @param out the stream
*/
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(targetClassName);
out.writeInt(hashCode);
}
/** Read from the input stream.
* Creates a new instance with the target class name set
*/
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
targetClass = null;
targetClassName = (String)in.readObject();
hashCode = in.readInt();
}
}