001    package com.sptci.jdo;
002    
003    import java.io.Serializable;
004    import java.util.Collection;
005    import java.util.HashSet;
006    import javax.jdo.InstanceCallbacks;
007    
008    import com.thoughtworks.xstream.XStream;
009    
010    /**
011     * A base object from which all the <code>JDO Object</code> 
012     * classes will be derived.  Provides default implementations for 
013     * common methods.
014     *
015     * @author Rakesh Vidyadharan 05<sup><small>th</small></sup> February, 2006
016     * <p>Copyright 2006, Sans Pareil Technologies, Inc.</p>
017     *
018     * @version $Id: JDOObject.java,v 1.2 2006/02/15 00:48:26 rakesh Exp $
019     */
020    public abstract class JDOObject 
021      implements Cloneable, Comparable<JDOObject>, Serializable, InstanceCallbacks
022    {
023      /**
024       * The default value to use for {@link #hash}.
025       */
026      protected static final int HASH = 7;
027    
028      /**
029       * The integer that represents the hash code for this object.
030       */
031      protected int hash = HASH;
032    
033      /**
034       * A collection of words used to perform whole-word search across
035       * each <code>Extent</code> in the database.
036       */
037      protected transient Collection<String> words = new HashSet<String>();
038    
039      /**
040       * A collection of metaphone words used to perform a search across
041       * each <code>Extent</code> in the database for similar sounding
042       * words.
043       */
044      protected transient Collection<String> metaphones = new HashSet<String>();
045    
046      /**
047       * Default constructor.  Initialise {@link #words} and {@link #metaphones}
048       * with empty collections.  Cannot be instantiated.
049       */
050      protected JDOObject()
051      {
052        words = new HashSet<String>();
053        metaphones = new HashSet<String>();
054      }
055    
056      /**
057       * Return a string representation of this object.  Return an XML
058       * representation of the data-fields.
059       *
060       * @see #toXML
061       * @return String The xml representation of this class.
062       */
063      @Override
064      public String toString()
065      {
066        return toXML();
067      }
068    
069      /**
070       * Return a hash code for this object.
071       */
072      @Override
073      public abstract int hashCode();
074    
075      /**
076       * Compare the specified object with this object for equality.  
077       * Returns <code>true</code> if the specified object is of the
078       * same type as this  object, and the values of {@link #hashCode}
079       * match.
080       *
081       * @param object The object that is to compared with this object.
082       * @return boolean Returns <code>true</code> if the objects have
083       *   the same hash code.
084       */
085      @Override
086      public abstract boolean equals( Object object );
087    
088      /**
089       * Creates and returns a copy of this object.  Implementation of
090       * the <code>Cloneable</code> interface.  No special actions are
091       * performed.  This method simply allows public access to the
092       * <code>Object.clone</code> method.
093       *
094       * @return Object A clone of this instance.
095       * @throws CloneNotSupportedException If the super-class implementation
096       *   throws an error.
097       */
098      @Override
099      public Object clone() throws CloneNotSupportedException
100      {
101        return super.clone();
102      }
103    
104      /**
105       * Compares this object with the specified object for order. Returns 
106       * a negative integer, zero, or a positive integer as this object is 
107       * less than, equal to, or greater than the specified object.
108       *
109       * <p><b>Note:</b> The default implementation just compares the
110       * {@link #hashCode} values.  It is recommended that sub-classes
111       * over-ride this method for appropriate sort order.</p>
112       *
113       * @param object The object that is to be compared with this object.
114       * @return int A negative integer, zero, or a positive integer as 
115       *   this object is less than, equal to, or greater than the 
116       *   specified object.
117       */
118      public int compareTo( JDOObject object )
119      {
120        return ( hashCode() - object.hashCode() );
121      }
122    
123      /**
124       * Return the utility used to convert the object to and from XML 
125       * representation.  This method must be used by the {@link #toXML}
126       * and {@link #fromXML} methods to initialise the serialiser in a
127       * standard manner.
128       */
129      protected static XStream createXStream()
130      {
131        XStream xstream = new XStream();
132        xstream.alias( "JDOObject", JDOObject.class );
133        return xstream;
134      }
135    
136      /**
137       * Return an XML representation of the fields of this object.
138       * It is recommended that sub-classes over-ride this method to
139       * specify good aliases for fully qualified class names to make
140       * the XML for readable.
141       *
142       * <p><b>Note:</b> Currently this method uses the 
143       * <a href='http://xstream.codehaus.org/'>XStream</a> API to
144       * convert the object into XML.  This may be modified at a later
145       * date to convert into a TMS standard XML format.</p>
146       *
147       * @see #createXStream
148       * @see #fromXML
149       * @return String - The string representation of this object.
150       */
151      public String toXML()
152      {
153        return createXStream().toXML( this );
154      }
155    
156      /**
157       * Parse the object out of the XML representation of this object.
158       * It is recommended that sub-classes over-ride this method to
159       * specify good aliases for fully qualified class names to make
160       * the XML for readable.
161       *
162       * @see #createXStream
163       * @see #toXML
164       * @param xml The XML representation of this object.
165       * @return Program The object parsed out of the XML representation.
166       */
167      public static JDOObject fromXML( String xml )
168      {
169        return (JDOObject) createXStream().fromXML( xml );
170      }
171    
172      /**
173       * Reset the {@link #hash} value.
174       */
175      public final void resetHash()
176      {
177        hash = HASH;
178      }
179    
180      /**
181       * Copy constructor equivalent.  Update the fields of the class 
182       * from the specified instance.
183       *
184       * @param object The instance from which the fields of this object
185       *   are to be updated.
186       */
187      protected abstract <E extends JDOObject> void copy( E object );
188    
189      /**
190       * InstanceCallbacks method implementation.  No actions required
191       * by default.
192       */
193      public void jdoPostLoad() {}
194    
195      /**
196       * InstanceCallbacks method implementation.  No actions required.
197       */
198      public void jdoPreStore() {}
199    
200      /**
201       * InstanceCallbacks method implementation.  No actions required.
202       */
203      public void jdoPreClear() {}
204    
205      /**
206       * InstanceCallbacks method implementation.  No actions required.
207       */
208      public void jdoPreDelete() {}
209    }