com.waveset.object
Class ObjectRef

java.lang.Object
  extended bycom.waveset.util.AbstractXmlObject
      extended bycom.waveset.object.ObjectRef
All Implemented Interfaces:
java.lang.Comparable, javax.naming.Referenceable, XmlObject

public class ObjectRef
extends AbstractXmlObject
implements java.lang.Comparable

An ObjectRef represents a reference from one PersistentObject to another. Since the XML serialization of an object cannot include the referenced objects, we need a stable "pointer" to that object. Sometimes, we want to refer not necessarily to the object, but specific contents of the object (such as a Rule in a RuleLibrary, perhaps). To support this sort of reference, the reference can be additionally qualified.

A reference consists of a type and two strings that may be used to identify objects of this type. Each stored persistent object will have both an id which is system generated and immutable, and a name which is user supplied and may change. The reference object may hold all three of these values.

Objects which have not been stored will have only a name. A reference with only a name may be created to an object that also has an id, this is sometimes done by applications since ids are not known, but the system will try to resolve the id before storage.

In addition to the fields representing the reference, the object may also contain a handle to an ObjectHandle. References of this form are said to be "resolved". An ObjectHandle in turn points to a PersistentObject. The ObjectHandle sits between the ObjectRef and the PersistentObject so we have an effecient mechanism for swapping in new versions of the object without having to track and update all references to the object. ObjectHandles will normally be maintained by an ObjectCache. It is possible to create a "free" ObjectHandle that isn't managed by an ObjectCache, and will not track object updates. This might happen if you were building an object hierarch from scratch without using a cache.

When a reference is resolved, we remove the name and id fields from the ObjectRef so that they may be garbage collected.

In the process of resolving a reference, it may be determined that there is no object with this identity, in this case the referrence object may be maked as "deleted". References marked deleted will be supressed when serializing XML. UPDATE: We could represent the same thing using an ObjectHandle with a pointer of null.

Reference resolution is performed by a higher level object, in current usage this is always the ObjectCache.

The following combination of field values are considered legal:

Type, Id, Name

This is the most common form, all fields are known. References that are stored in the repository, and which have been resolved at least once will have this form. When both the id and name appear, the id is always preferred for repository lookups, since it is possible for the name of the target object to have been changed.

Type, Id

The object is referenced by ID, but the name is not known. This is an unusual form.

Type, Name

The object is referenced by name, but the id is not known. This is a common form when objects are being created by an application in response to input from the user. Since users typically do not know object ids, references are specified by name. The system will later attempt to resolve the reference, and fill in the id.

Type, Handle

This is the resolved form. The id and name are not stored in the reference, but we have a handle to an object where the id/name can be found.


Nested Class Summary
static class ObjectRef.NameComparator
          Implement the Comparator interface to sort ObjectRef instances by name and id.
 
Field Summary
static java.lang.String code_id
           
static java.lang.String ELEMENT
          Our XML element name.
static ObjectRef.NameComparator NAME_COMPARATOR
           
static java.lang.String WRAPPER_ELEMENT
          Default XML element name used for wrapper elements around lists of reference objects.
 
Fields inherited from class com.waveset.util.AbstractXmlObject
_trace
 
Constructor Summary
  ObjectRef(org.w3c.dom.Element e)
          Build an object ref, by parsing its XML representation.
protected ObjectRef(com.waveset.object.ObjectHandle h)
          Build a resolved reference to a persistent object.
  ObjectRef(ObjectRef ref)
          Build an object ref by performing a "shallow copy" of another reference.
  ObjectRef(PersistentObject o)
          Build a reference to the given persistent object.
  ObjectRef(Type type, java.lang.String nameOrId)
          Build an unresolved reference, given a name or id.
  ObjectRef(Type type, java.lang.String id, java.lang.String name)
          Build an unresolved reference, given explicit field values.
  ObjectRef(Type type, java.lang.String id, java.lang.String name, java.lang.String displayName)
          Build an unresolved reference, given explicit field values.
 
Method Summary
static java.util.List cloneObjectRefList(java.util.List src)
          Clone a list of ObjectRefs, making new objects.
 int compareTo(java.lang.Object o)
          Implement the comparable interface so that lists of these will have a reasonable contains() implementation
 void confirmValid()
          Generates annoying displays (or exceptions) when an invalid ObjectRef is constructed.
static java.util.ArrayList copyReferences(java.util.ArrayList srclist)
          A helper method that clones a list of object references.
static ObjectRef create(PersistentObject obj)
          Added after the ObjectRef constructors started throwing exceptions.
static ObjectRef create(Type type, java.lang.String nameOrId)
          Added after the ObjectRef constructors started throwing exceptions.
static ObjectRef create(Type type, java.lang.String id, java.lang.String name)
          Added after the ObjectRef constructors started throwing exceptions.
static ObjectRef create(Type type, java.lang.String id, java.lang.String name, java.lang.String displayName)
          Added after the ObjectRef constructors started throwing exceptions.
 boolean equals(java.lang.Object obj)
          Compares the reference with another object for equality.
 java.lang.String getDisplayableName()
          Get the displayable name for the referenced object.
 java.lang.String getDisplayName()
          Get the display name for the referenced object.
 java.lang.String getElementName()
          Get the XML element name, required by XmlObject.
protected  com.waveset.object.ObjectHandle getHandle()
          Get the resolved object handle.
 java.lang.String getId()
          Get the referenced object id.
 java.lang.String getIdOrName()
          Get the id if it has been assigned, otherwise the name.
 java.lang.String getName()
          Get the referenced object name.
 java.lang.String getNameOrId()
          Get the name if it has been assigned, otherwise the id.
 PersistentObject getObject()
          Get the resolved object.
static java.util.List getObjectNames(java.util.List src)
          Take a list of ObjectRefs or objects, turn that into a list of String names
 java.lang.String getQualifier()
          Get the qualifier for the reference.
 Type getType()
          Get the type of the reference.
 int hashCode()
          Implement the hashCode for efficient map insertion
 boolean isDeleted()
          Tests the deleted status of the reference.
 boolean isIdentityEqual(ObjectRef oref)
          Helper method for equals.
 boolean isIdentityEqual(ObjectRef oref, boolean checkQualifiers)
          Helper method for equals.
 boolean isQualified()
          Indicates whether the reference is qualified.
 boolean isReferencing(PersistentObject pobj)
          Returns true if this object is referencing the given persistent object.
 void parseXml(org.w3c.dom.Element e)
          Parse the XML representation of a reference, and set the corresponding fields.
static ObjectRef[] parseXmlArray(org.w3c.dom.Element e)
          Builds an array of reference objects by parsing the XML representation of a reference list.
static java.util.ArrayList parseXmlList(org.w3c.dom.Element e)
          Builds an ArrayList of reference objects by parsing the XML representation of a reference list.
static ObjectRef parseXmlWrapper(org.w3c.dom.Element e)
          Constructs an object reference by parsing an XML wrapper element.
protected  void setDeleted(boolean d)
          Set the deleted status of the reference.
 void setdisplayName(java.lang.String displayName)
          Set the referenced object display name.
protected  void setHandle(com.waveset.object.ObjectHandle h)
          Set the resolved object handle.
 void setId(java.lang.String id)
          Set the referenced object id.
 void setName(java.lang.String name)
          Set the referenced object name.
 void setQualifier(java.lang.String qualifier)
          Set the qualifier for the reference.
 java.lang.String toString()
          Overrides java.lang.object.
 void toXml(java.lang.StringBuffer b, int indent)
          Serialize the object into an XML buffer.
 void toXml(java.lang.StringBuffer b, int indent, java.lang.String wrapper)
          Serialize the object to an XML buffer, optionally wrapping it in another element.
static void toXmlList(java.lang.StringBuffer b, int indent, java.lang.String wrapper, java.util.Collection refs)
          Serialize a collection of references to an XML buffer.
static void toXmlList(java.lang.StringBuffer b, int indent, java.lang.String wrapper, ObjectRef[] refs)
          Serialize an array of references to an XML buffer.
 void unresolve()
          Unresolve a reference, occasionally used when transfering an object from one cache to another to remove resolved references between caches.
 
Methods inherited from class com.waveset.util.AbstractXmlObject
addXmlHeader, cloneObject, dump, dumpFile, getReference, println, setTrace, toIdentityString, toVerboseString, toVerboseString, toXml, toXml, toXml
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

code_id

public static final java.lang.String code_id
See Also:
Constant Field Values

ELEMENT

public static final java.lang.String ELEMENT
Our XML element name.

See Also:
Constant Field Values

WRAPPER_ELEMENT

public static final java.lang.String WRAPPER_ELEMENT
Default XML element name used for wrapper elements around lists of reference objects.

See Also:
Constant Field Values

NAME_COMPARATOR

public static ObjectRef.NameComparator NAME_COMPARATOR
Constructor Detail

ObjectRef

public ObjectRef(Type type,
                 java.lang.String id,
                 java.lang.String name)
Build an unresolved reference, given explicit field values.


ObjectRef

public ObjectRef(Type type,
                 java.lang.String id,
                 java.lang.String name,
                 java.lang.String displayName)
Build an unresolved reference, given explicit field values.


ObjectRef

public ObjectRef(Type type,
                 java.lang.String nameOrId)
Build an unresolved reference, given a name or id.

I didn't want to provide this, but there's too much legacy code that was using this form, and as long as we can reliably determine what ids look like it isn't that bad.


ObjectRef

protected ObjectRef(com.waveset.object.ObjectHandle h)
Build a resolved reference to a persistent object. This should be called only by the cache manager.


ObjectRef

public ObjectRef(PersistentObject o)
Build a reference to the given persistent object.

I'm inclined to make this protected, but there is code that uses ObjectRef as a convenient way to bundle up a type/id/name tuple rather than passing the object around.


ObjectRef

public ObjectRef(org.w3c.dom.Element e)
          throws WavesetException
Build an object ref, by parsing its XML representation. Required by XmlObject.


ObjectRef

public ObjectRef(ObjectRef ref)
Build an object ref by performing a "shallow copy" of another reference. This will capture the type, id and name, but not the resolved object handle. This should be used when assigning a reference object owned by one object to another object.

Method Detail

confirmValid

public void confirmValid()
                  throws InternalError
Generates annoying displays (or exceptions) when an invalid ObjectRef is constructed.

Throws:
InternalError

create

public static ObjectRef create(PersistentObject obj)
Added after the ObjectRef constructors started throwing exceptions. This can be used as a convenience method for those places that know they're building a valid reference and don't want to catch exceptions.


create

public static ObjectRef create(Type type,
                               java.lang.String nameOrId)
Added after the ObjectRef constructors started throwing exceptions. This can be used as a convenience method for those places that know they're building a valid reference and don't want to catch exceptions.


create

public static ObjectRef create(Type type,
                               java.lang.String id,
                               java.lang.String name)
Added after the ObjectRef constructors started throwing exceptions. This can be used as a convenience method for those places that know they're building a valid reference and don't want to catch exceptions.


create

public static ObjectRef create(Type type,
                               java.lang.String id,
                               java.lang.String name,
                               java.lang.String displayName)
Added after the ObjectRef constructors started throwing exceptions. This can be used as a convenience method for those places that know they're building a valid reference and don't want to catch exceptions.


copyReferences

public static java.util.ArrayList copyReferences(java.util.ArrayList srclist)
A helper method that clones a list of object references. The refrences are created with "shallow copy". This should be used when trying to assign a reference list from one object to another.


getObjectNames

public static java.util.List getObjectNames(java.util.List src)
                                     throws WavesetException
Take a list of ObjectRefs or objects, turn that into a list of String names

Throws:
WavesetException

getElementName

public java.lang.String getElementName()
Get the XML element name, required by XmlObject.

Specified by:
getElementName in interface XmlObject
Specified by:
getElementName in class AbstractXmlObject

getType

public Type getType()
Get the type of the reference.


getId

public java.lang.String getId()
Get the referenced object id.

A reference may not have an id, but if it doesn't the name should be set.


getIdOrName

public java.lang.String getIdOrName()
Get the id if it has been assigned, otherwise the name.


getNameOrId

public java.lang.String getNameOrId()
Get the name if it has been assigned, otherwise the id. This is typically used for visible messages where we want to prefer the name over the id.


setId

public void setId(java.lang.String id)
           throws InternalError
Set the referenced object id.

This is provided as a public accessor since we may not always know the id of the object at the time the reference is constructed. This is valid only if we don't have a resolved handle.

Throws:
InternalError

getName

public java.lang.String getName()
Get the referenced object name.

A reference may not have a name, but if it doesn't the id should be set.


setName

public void setName(java.lang.String name)
             throws InternalError
Set the referenced object name.

This is provided as a public accessor since we may not always know the object name at the time the reference is constructed. The object name could in theory change after construction if a rename was detected? Though I think that would be handled by the resolved object.

Throws:
InternalError

getDisplayName

public java.lang.String getDisplayName()
Get the display name for the referenced object.


getDisplayableName

public java.lang.String getDisplayableName()
Get the displayable name for the referenced object.


setdisplayName

public void setdisplayName(java.lang.String displayName)
Set the referenced object display name.


isQualified

public boolean isQualified()
Indicates whether the reference is qualified.


getQualifier

public java.lang.String getQualifier()
Get the qualifier for the reference.


setQualifier

public void setQualifier(java.lang.String qualifier)
Set the qualifier for the reference.


toString

public java.lang.String toString()
Overrides java.lang.object.


getObject

public PersistentObject getObject()
Get the resolved object.

Note that this doesn't attempt to resolve the reference, it only returns the object if it has already been resolved.

See Also:
PersistentObject.resolveReference(com.waveset.object.ObjectRef), ObjectCache.resolve(com.waveset.object.ObjectRef)

getHandle

protected com.waveset.object.ObjectHandle getHandle()
Get the resolved object handle. Only for use by ObjectCache.


setHandle

protected void setHandle(com.waveset.object.ObjectHandle h)
Set the resolved object handle.

Assigning null means to detatch from the handle, but we capture the identity before we do.


unresolve

public void unresolve()
Unresolve a reference, occasionally used when transfering an object from one cache to another to remove resolved references between caches.


isDeleted

public boolean isDeleted()
Tests the deleted status of the reference.

This will normally be set by the ObjectCache as resolution happens and it detects that the referenced object doesn't exist. Once this is set, the serialization methods will suppress the reference.


setDeleted

protected void setDeleted(boolean d)
Set the deleted status of the reference. This should only be called by ObjectCache.


isReferencing

public boolean isReferencing(PersistentObject pobj)
Returns true if this object is referencing the given persistent object.

// jsl - I added this and made it public since overloading // equals always causes problems when you use collection classes. // Also having two completely different classes be equal() feels wrong.


equals

public boolean equals(java.lang.Object obj)
Compares the reference with another object for equality.

This method overrides the java.lang.Object equals method. It determines equality based on whether the identities of the current object ref and the object argument are equal, where equal is defined as:

  1. The object argument is either an instance of a PersistentObject or an ObjectRef
  2. The types must match
  3. If both ids are not null, they must be the same
  4. If either or both ids are null, then the names must be the same.

jsl - Defining equality for objects of completely different classes feels strange, but it is convenient for use in Collections of ObjectRef or PersistentObject objects.

For single object reference comparison, the isReferencing method is also available.

See Also:
isReferencing(com.waveset.object.PersistentObject)

compareTo

public int compareTo(java.lang.Object o)
Implement the comparable interface so that lists of these will have a reasonable contains() implementation

Specified by:
compareTo in interface java.lang.Comparable

hashCode

public int hashCode()
Implement the hashCode for efficient map insertion


isIdentityEqual

public boolean isIdentityEqual(ObjectRef oref,
                               boolean checkQualifiers)
Helper method for equals. Compares two reference objects for equality, optionally considering qualifiers.


isIdentityEqual

public boolean isIdentityEqual(ObjectRef oref)
Helper method for equals. Compares two reference objects for equality, considering qualifiers.


toXml

public void toXml(java.lang.StringBuffer b,
                  int indent,
                  java.lang.String wrapper)
Serialize the object to an XML buffer, optionally wrapping it in another element. If the referenced object has been marked as deleted, or is invalid, then nothing is added to the buffer.

Wrappers are commonly used the serialization methods of other objects so they can put some context around the reference.


toXml

public void toXml(java.lang.StringBuffer b,
                  int indent)
Serialize the object into an XML buffer.

Specified by:
toXml in interface XmlObject
Specified by:
toXml in class AbstractXmlObject

parseXml

public void parseXml(org.w3c.dom.Element e)
              throws WavesetException
Parse the XML representation of a reference, and set the corresponding fields.

Throws:
WavesetException

toXmlList

public static void toXmlList(java.lang.StringBuffer b,
                             int indent,
                             java.lang.String wrapper,
                             ObjectRef[] refs)
Serialize an array of references to an XML buffer.

This is a convenience method for persistent objects that maintain collections of references. The list will be wrapped in an element named "ObjectRefs" unless an alternate wrapper name is given.

If there are no references in the array, or all references have been marked deleted, nothing is added to the buffer.


toXmlList

public static void toXmlList(java.lang.StringBuffer b,
                             int indent,
                             java.lang.String wrapper,
                             java.util.Collection refs)
Serialize a collection of references to an XML buffer.

This is a convenience method for persistent objects that maintain collections of references. The list will be wrapped in an element named "ObjectRefs" unless an alternate wrapper name is given.

If there are no references in the array, or all references have been marked deleted, nothing is added to the buffer.


parseXmlWrapper

public static ObjectRef parseXmlWrapper(org.w3c.dom.Element e)
                                 throws WavesetException
Constructs an object reference by parsing an XML wrapper element.

The wrapper is expected to have a single child element.

Throws:
WavesetException

parseXmlList

public static java.util.ArrayList parseXmlList(org.w3c.dom.Element e)
                                        throws WavesetException
Builds an ArrayList of reference objects by parsing the XML representation of a reference list.

The provided element is expected to be the wrapper elements, its name is unimportant. We extract any elements contained in the wrapper.

Throws:
WavesetException

parseXmlArray

public static ObjectRef[] parseXmlArray(org.w3c.dom.Element e)
                                 throws WavesetException
Builds an array of reference objects by parsing the XML representation of a reference list.

The provided element is expected to be the wrapper elements, its name is unimportant. We extract any elements contained in the wrapper.

Now that we're moving toward representing reference collections using ArrayList rather than Java arrays, this method should atrophy.

Throws:
WavesetException

cloneObjectRefList

public static java.util.List cloneObjectRefList(java.util.List src)
Clone a list of ObjectRefs, making new objects.