package net.sourceforge.fenixedu.domain; import java.io.Serializable; import net.sourceforge.fenixedu.domain.exceptions.DomainException; import pt.ist.fenixframework.pstm.Transaction; /** * A DomainReference allows a serializable object to refer to a * domain object. The DomainReference introduces an indirection * point between the holder object and the domain object that avoids any data * from the domain object to be stored in the serialization point. * * @author cfgi */ public class DomainReference implements Serializable { private static final long serialVersionUID = 1L; private String className; // is also used to know when we are storing the // null value private Integer oid; transient Class type; // chached type, transient to protect from class // hierarchy changes transient T object; public DomainReference(T object) { if (object == null) { this.object = null; this.type = null; this.className = null; this.oid = null; } else { this.object = object; this.type = object.getClass(); this.className = object.getClass().getName(); this.oid = object.getIdInternal(); } } public DomainReference(Class clazz, Integer oid) { this.type = clazz; this.className = clazz.getName(); this.oid = oid; } /** * Allows you to check if a certain {@link DomainReference} is a refenrece * to null. Note that, when a domain reference is a null * renference, you can still get a null value from * {@link #getObject()} when the referenced object no longer exists. * * @return true if the domain reference is an explicit * reference to null */ public boolean isNullReference() { return this.className == null; } public Integer getOid() { return this.oid; } protected String getClassName() { return this.className; } public Class getType() { if (this.className == null) { return null; } if (this.type != null) { return this.type; } else { try { return this.type = Class.forName(getClassName()); } catch (ClassNotFoundException e) { throw new DomainException("reference.notFound.class", e, getClassName()); } } } public T getObject() { if (this.object != null) { // cache return this.object; } if (this.className == null) { // null object return null; } this.object = (T) Transaction.getDomainObject(getClassName(), getOid()); return this.object; } @Override public boolean equals(Object other) { if (!(other instanceof DomainReference)) { return false; } DomainReference otherReference = (DomainReference) other; if (this.getOid() == null && otherReference.getOid() != null) { return false; } if (this.getOid() != null && !this.getOid().equals(otherReference.getOid())) { return false; } if (this.getType() == null && otherReference.getType() != null) { return false; } if (this.getType() != null && !this.getType().equals(otherReference.getType())) { return false; } return true; } @Override public int hashCode() { int oidHash; int typeHash; oidHash = getOid() == null ? 0 : getOid().hashCode(); typeHash = getType() == null ? 0 : getType().hashCode(); return oidHash + typeHash; } @Override public String toString() { if (this.className == null) { return ""; } else { return String.format("%s:%s", this.className, this.oid); } } }