1 /** 2 * Copyright 2005 Steve Molloy 3 * 4 * This file is part of OV4J. 5 * 6 * OV4J is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 8 * 9 * OV4J is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License along with OV4J; if not, write to the Free Software 13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 14 * 15 */ 16 package org.ov4j.data; 17 18 import java.io.Serializable; 19 import java.lang.reflect.Array; 20 import java.lang.reflect.InvocationTargetException; 21 import java.lang.reflect.Method; 22 import java.util.logging.Level; 23 import java.util.logging.Logger; 24 25 /** 26 * Container allowing to store any object in versions. 27 * 28 * @author smolloy 29 * 30 */ 31 public class ClassComparable implements Comparable<ClassComparable>, Cloneable, Serializable { 32 /** 33 * Logger for this class 34 */ 35 private static final Logger logger = Logger.getLogger(ClassComparable.class.getName()); 36 37 /** Serial UID */ 38 private static final long serialVersionUID = 3548676343171491377L; 39 40 /** Object to be stored. */ 41 private Object theObject; 42 43 /** 44 * Constructor. 45 * 46 */ 47 public ClassComparable() { 48 } 49 50 /** 51 * @see org.ov4j.data.VersionableObject#clone() 52 */ 53 @Override 54 public ClassComparable clone() throws CloneNotSupportedException { 55 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 56 ClassComparable.logger.entering("ClassComparable", "clone()", "start"); 57 } 58 59 final ClassComparable returnClassComparable = (ClassComparable) super.clone(); 60 if (theObject != null) { 61 Method clone; 62 try { 63 clone = theObject.getClass().getMethod("clone", new Class[0]); 64 returnClassComparable.theObject = clone.invoke(theObject, new Object[0]); 65 } catch (final SecurityException e) { 66 if (ClassComparable.logger.isLoggable(Level.FINE)) { 67 ClassComparable.logger.logp(Level.FINE, "Item", "clone()", "Exception caught", e); 68 } 69 70 throw new CloneNotSupportedException(e.toString()); 71 } catch (final NoSuchMethodException e) { 72 if (ClassComparable.logger.isLoggable(Level.FINE)) { 73 ClassComparable.logger.logp(Level.FINE, "Item", "clone()", "Exception caught", e); 74 } 75 76 throw new CloneNotSupportedException(e.toString()); 77 } catch (final IllegalArgumentException e) { 78 if (ClassComparable.logger.isLoggable(Level.FINE)) { 79 ClassComparable.logger.logp(Level.FINE, "Item", "clone()", "Exception caught", e); 80 } 81 82 throw new CloneNotSupportedException(e.toString()); 83 } catch (final IllegalAccessException e) { 84 if (ClassComparable.logger.isLoggable(Level.FINE)) { 85 ClassComparable.logger.logp(Level.FINE, "Item", "clone()", "Exception caught", e); 86 } 87 88 throw new CloneNotSupportedException(e.toString()); 89 } catch (final InvocationTargetException e) { 90 if (ClassComparable.logger.isLoggable(Level.FINE)) { 91 ClassComparable.logger.logp(Level.FINE, "Item", "clone()", "Exception caught", e); 92 } 93 94 throw new CloneNotSupportedException(e.toString()); 95 } 96 } 97 98 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 99 ClassComparable.logger.exiting("ClassComparable", "clone()", "end - return value=" + returnClassComparable); 100 } 101 return returnClassComparable; 102 } 103 104 /** 105 * @see org.ov4j.data.VersionableObject#compareTo(T) 106 */ 107 @Override 108 public int compareTo(final ClassComparable o) { 109 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 110 ClassComparable.logger.entering("ClassComparable", "compareTo(ClassComparable=" + o + ")", "start"); 111 } 112 113 if (o == null) { 114 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 115 ClassComparable.logger.exiting("ClassComparable", "compareTo(ClassComparable=null)", 116 "end - return value=" + 1); 117 } 118 return 1; 119 } 120 121 if (theObject == null) { 122 final int returnint = (o.getTheObject() == null) ? 0 : -1; 123 124 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 125 ClassComparable.logger.exiting("ClassComparable", "compareTo(ClassComparable=" + o + ")", 126 "end - return value=" + returnint); 127 } 128 return returnint; 129 } 130 131 if (o.getTheObject() == null) { 132 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 133 ClassComparable.logger.exiting("ClassComparable", "compareTo(ClassComparable=" + o + ")", 134 "end - return value=" + 1); 135 } 136 return 1; 137 } 138 139 int res = theObject.getClass().getName().compareTo(o.getTheObject().getClass().getName()); 140 if (res == 0) { 141 if (theObject.getClass().isArray() && o.getTheObject().getClass().isArray()) { 142 res = Integer.valueOf(Array.getLength(theObject)).compareTo(Array.getLength(o.getTheObject())); 143 for (int i = 0; res == 0 && i < Array.getLength(theObject); i++) { 144 final Object a1 = Array.get(theObject, i); 145 final Object a2 = Array.get(o.getTheObject(), i); 146 if (a1 instanceof Comparable && a2 instanceof Comparable) { 147 res = ((Comparable) a1).compareTo(a2); 148 } 149 } 150 } else if (theObject instanceof Comparable) { 151 res = ((Comparable) theObject).compareTo(o.getTheObject()); 152 } 153 } 154 155 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 156 ClassComparable.logger.exiting("ClassComparable", "compareTo(ClassComparable=" + o + ")", 157 "end - return value=" + res); 158 } 159 return res; 160 } 161 162 /** 163 * @see java.lang.Object#equals(java.lang.Object) 164 */ 165 @Override 166 public boolean equals(final Object o) { 167 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 168 ClassComparable.logger.entering("ClassComparable", "equals(Object=" + o + ")", "start"); 169 } 170 171 final boolean returnboolean = o instanceof ClassComparable && compareTo((ClassComparable) o) == 0; 172 173 if (ClassComparable.logger.isLoggable(Level.FINEST)) { 174 ClassComparable.logger.exiting("ClassComparable", "equals(Object=" + o + ")", "end - return value=" 175 + returnboolean); 176 } 177 return returnboolean; 178 } 179 180 /** 181 * @return Returns the object. 182 */ 183 public Object getTheObject() { 184 return theObject; 185 } 186 187 /** 188 * @see java.lang.Object#hashCode() 189 */ 190 @Override 191 public int hashCode() { 192 return (theObject == null ? 0 : theObject.hashCode()); 193 } 194 195 /** 196 * @param theObject 197 * The object to set. 198 */ 199 public void setTheObject(final Object theObject) { 200 this.theObject = theObject; 201 } 202 203 /** 204 * @see java.lang.Object#toString() 205 */ 206 @Override 207 public String toString() { 208 return "ClassComparable( " + ((theObject == null) ? "null" : theObject.toString()) + ")"; 209 } 210 }