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 }