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.InvocationTargetException; 20 import java.lang.reflect.Method; 21 import java.util.logging.Level; 22 import java.util.logging.Logger; 23 24 /** 25 * This class represents a version in the system. 26 * 27 * @author smolloy 28 * 29 */ 30 public class Version<T extends Serializable & Comparable<? super T> & Cloneable> implements Cloneable, 31 Comparable<Version<T>>, Serializable { 32 /** 33 * Logger for this class 34 */ 35 private static final Logger logger = Logger.getLogger(Version.class.getName()); 36 37 /** Serial UID */ 38 private static final long serialVersionUID = 9097677006080708756L; 39 40 public static final Version<?>[] EMPTY_ARRAY = new Version[0]; 41 42 /** Author of this version. */ 43 private String author; 44 45 /** Comment used to commit this version. */ 46 private String comment; 47 48 /** Version timestamp. */ 49 private long versionTimestamp; 50 51 /** Number of this version. */ 52 private int versionNumber; 53 54 /** Object being versioned. */ 55 private T versionedObject; 56 57 /** 58 * Constructor. 59 */ 60 public Version() { 61 } 62 63 /** 64 * @see java.lang.Object#clone() 65 */ 66 @Override 67 public Version<T> clone() throws CloneNotSupportedException { 68 if (Version.logger.isLoggable(Level.FINEST)) { 69 Version.logger.entering("Version", "clone()", "start"); 70 } 71 72 final Version<T> newVersion = (Version<T>) super.clone(); 73 if (versionedObject != null) { 74 try { 75 final Method clone = versionedObject.getClass().getMethod("clone", new Class[0]); 76 newVersion.versionedObject = (T) clone.invoke(versionedObject, new Object[0]); 77 } catch (final SecurityException e) { 78 if (Version.logger.isLoggable(Level.FINE)) { 79 Version.logger.logp(Level.FINE, "Version", "clone()", "Exception caught", e); 80 } 81 82 throw new CloneNotSupportedException(e.toString()); 83 } catch (final NoSuchMethodException e) { 84 if (Version.logger.isLoggable(Level.FINE)) { 85 Version.logger.logp(Level.FINE, "Version", "clone()", "Exception caught", e); 86 } 87 88 throw new CloneNotSupportedException(e.toString()); 89 } catch (final IllegalArgumentException e) { 90 if (Version.logger.isLoggable(Level.FINE)) { 91 Version.logger.logp(Level.FINE, "Version", "clone()", "Exception caught", e); 92 } 93 94 throw new CloneNotSupportedException(e.toString()); 95 } catch (final IllegalAccessException e) { 96 if (Version.logger.isLoggable(Level.FINE)) { 97 Version.logger.logp(Level.FINE, "Version", "clone()", "Exception caught", e); 98 } 99 100 throw new CloneNotSupportedException(e.toString()); 101 } catch (final InvocationTargetException e) { 102 if (Version.logger.isLoggable(Level.FINE)) { 103 Version.logger.logp(Level.FINE, "Version", "clone()", "Exception caught", e); 104 } 105 106 throw new CloneNotSupportedException(e.toString()); 107 } 108 } 109 110 if (Version.logger.isLoggable(Level.FINEST)) { 111 Version.logger.exiting("Version", "clone()", "end - return value=" + newVersion); 112 } 113 return newVersion; 114 } 115 116 /** 117 * @see java.lang.Comparable#compareTo(T) 118 */ 119 public int compareTo(final Version<T> v) { 120 if (Version.logger.isLoggable(Level.FINEST)) { 121 Version.logger.entering("Version", "compareTo(Version<T>=" + v + ")", "start"); 122 } 123 124 if (v == null) { 125 if (Version.logger.isLoggable(Level.FINEST)) { 126 Version.logger.exiting("Version", "compareTo(Version<T>=null)", "end - return value=" + 1); 127 } 128 return 1; 129 } 130 131 if (versionedObject == null) { 132 final int returnint = (v.getVersionedObject() == null) ? 0 : -1; 133 134 if (Version.logger.isLoggable(Level.FINEST)) { 135 Version.logger.exiting("Version", "compareTo(Version<T>=" + v + ")", "end - return value=" + returnint); 136 } 137 return returnint; 138 } 139 140 int res = Integer.valueOf(versionNumber).compareTo(v.getVersionNumber()); 141 if (res == 0) { 142 res = versionedObject.compareTo(v.getVersionedObject()); 143 } 144 145 if (Version.logger.isLoggable(Level.FINEST)) { 146 Version.logger.exiting("Version", "compareTo(Version<T>=" + v + ")", "end - return value=" + res); 147 } 148 return res; 149 } 150 151 /** 152 * @see java.lang.Object#equals(java.lang.Object) 153 */ 154 @Override 155 public boolean equals(final Object o) { 156 if (Version.logger.isLoggable(Level.FINEST)) { 157 Version.logger.entering("Version", "equals(Object=" + o + ")", "start"); 158 } 159 160 final boolean returnboolean = o instanceof Version && compareTo((Version<T>) o) == 0; 161 162 if (Version.logger.isLoggable(Level.FINEST)) { 163 Version.logger.exiting("Version", "equals(Object=" + o + ")", "end - return value=" + returnboolean); 164 } 165 return returnboolean; 166 } 167 168 /** 169 * @return Returns the author. 170 */ 171 public String getAuthor() { 172 return author; 173 } 174 175 /** 176 * @return Returns the comment. 177 */ 178 public String getComment() { 179 return comment; 180 } 181 182 /** 183 * @return Returns the versionedObject. 184 */ 185 public T getVersionedObject() { 186 return versionedObject; 187 } 188 189 /** 190 * @return Returns the versionNumber. 191 */ 192 public int getVersionNumber() { 193 return versionNumber; 194 } 195 196 /** 197 * @return the versionTimestamp 198 */ 199 public long getVersionTimestamp() { 200 return versionTimestamp; 201 } 202 203 /** 204 * @see java.lang.Object#hashCode() 205 */ 206 @Override 207 public int hashCode() { 208 return (versionedObject == null ? 0 : versionedObject.hashCode()) + versionNumber; 209 } 210 211 /** 212 * @param author 213 * The author to set. 214 */ 215 public void setAuthor(final String author) { 216 this.author = author; 217 } 218 219 /** 220 * @param comment 221 * The comment to set. 222 */ 223 public void setComment(final String comment) { 224 this.comment = comment; 225 } 226 227 /** 228 * @param versionedObject 229 * The versionedObject to set. 230 */ 231 public void setVersionedObject(final T versionedObject) { 232 this.versionedObject = versionedObject; 233 } 234 235 /** 236 * @param versionNumber 237 * The versionNumber to set. 238 */ 239 public void setVersionNumber(final int versionNumber) { 240 this.versionNumber = versionNumber; 241 } 242 243 /** 244 * @param versionTimestamp 245 * the versionTimestamp to set 246 */ 247 public void setVersionTimestamp(final long versionTimestamp) { 248 this.versionTimestamp = versionTimestamp; 249 } 250 251 /** 252 * @see java.lang.Object#toString() 253 */ 254 @Override 255 public String toString() { 256 return "Version, Author: " + author + ", VersionNumber: " + versionNumber + ", VersionedObject: " 257 + ((versionedObject == null) ? "null" : versionedObject.toString()); 258 } 259 }