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 }