1 19 20 package org.apache.cayenne; 21 22 import java.io.Serializable ; 23 import java.util.ArrayList ; 24 import java.util.Arrays ; 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Map ; 30 31 import org.apache.cayenne.util.IDUtil; 32 import org.apache.cayenne.util.Util; 33 import org.apache.commons.lang.builder.EqualsBuilder; 34 import org.apache.commons.lang.builder.HashCodeBuilder; 35 36 45 public class ObjectId implements Serializable { 46 47 protected String entityName; 48 protected Map objectIdKeys; 49 50 private String singleKey; 51 private Object singleValue; 52 53 protected byte[] key; 54 55 protected Map replacementIdMap; 56 57 transient int hashCode; 59 60 private ObjectId() { 62 } 63 64 69 public ObjectId(String entityName) { 70 this.entityName = entityName; 71 this.key = IDUtil.pseudoUniqueByteSequence8(); 72 } 73 74 80 public ObjectId(String entityName, byte[] key) { 81 this.entityName = entityName; 82 this.key = key; 83 } 84 85 90 public ObjectId(String entityName, String key, int value) { 91 this(entityName, key, new Integer (value)); 92 } 93 94 99 public ObjectId(String entityName, String key, Object value) { 100 this.entityName = entityName; 101 102 this.singleKey = key; 103 this.singleValue = value; 104 } 105 106 111 public ObjectId(String entityName, Map idMap) { 112 this.entityName = entityName; 113 114 if (idMap == null || idMap.size() == 0) { 115 116 } 117 else if (idMap.size() == 1) { 118 Map.Entry e = (Map.Entry ) idMap.entrySet().iterator().next(); 119 this.singleKey = String.valueOf(e.getKey()); 120 this.singleValue = e.getValue(); 121 } 122 else { 123 124 this.objectIdKeys = new HashMap (idMap); 128 } 129 } 130 131 public boolean isTemporary() { 132 return key != null; 133 } 134 135 138 public String getEntityName() { 139 return entityName; 140 } 141 142 public byte[] getKey() { 143 return key; 144 } 145 146 151 public Map getIdSnapshot() { 152 if (isTemporary()) { 153 return (replacementIdMap == null) ? Collections.EMPTY_MAP : Collections 154 .unmodifiableMap(replacementIdMap); 155 } 156 157 if (singleKey != null) { 158 return Collections.singletonMap(singleKey, singleValue); 159 } 160 161 return objectIdKeys != null 162 ? Collections.unmodifiableMap(objectIdKeys) 163 : Collections.EMPTY_MAP; 164 } 165 166 public boolean equals(Object object) { 167 if (this == object) { 168 return true; 169 } 170 171 if (!(object instanceof ObjectId)) { 172 return false; 173 } 174 175 ObjectId id = (ObjectId) object; 176 177 if (!Util.nullSafeEquals(entityName, id.entityName)) { 178 return false; 179 } 180 181 if (isTemporary()) { 182 return new EqualsBuilder().append(key, id.key).isEquals(); 183 } 184 185 if (singleKey != null) { 186 return Util.nullSafeEquals(singleKey, id.singleKey) 187 && valueEquals(singleValue, id.singleValue); 188 } 189 190 if (id.objectIdKeys == null) { 191 return objectIdKeys == null; 192 } 193 194 if (id.objectIdKeys.size() != objectIdKeys.size()) { 195 return false; 196 } 197 198 Iterator entries = objectIdKeys.entrySet().iterator(); 199 while (entries.hasNext()) { 200 Map.Entry entry = (Map.Entry ) entries.next(); 201 Object entryKey = entry.getKey(); 202 Object entryValue = entry.getValue(); 203 204 if (entryValue == null) { 205 if (id.objectIdKeys.get(entryKey) != null 206 || !id.objectIdKeys.containsKey(entryKey)) { 207 return false; 208 } 209 } 210 else { 211 if (!valueEquals(entryValue, id.objectIdKeys.get(entryKey))) { 212 return false; 213 } 214 } 215 } 216 217 return true; 218 } 219 220 private final boolean valueEquals(Object o1, Object o2) { 221 if (o1 == o2) { 222 return true; 223 } 224 225 if (o1 == null) { 226 return o2 == null; 227 } 228 229 if (o1 instanceof Number ) { 230 return o2 instanceof Number 231 && ((Number ) o1).longValue() == ((Number ) o2).longValue(); 232 } 233 234 if (o1.getClass().isArray()) { 235 return new EqualsBuilder().append(o1, o2).isEquals(); 236 } 237 238 return Util.nullSafeEquals(o1, o2); 239 } 240 241 public int hashCode() { 242 243 if (this.hashCode == 0) { 244 245 HashCodeBuilder builder = new HashCodeBuilder(3, 5); 246 builder.append(entityName.hashCode()); 247 248 if (key != null) { 249 builder.append(key); 250 } 251 else if (singleKey != null) { 252 builder.append(singleKey.hashCode()); 253 254 if (singleValue instanceof Number ) { 256 builder.append(((Number ) singleValue).longValue()); 257 } 258 else { 259 builder.append(singleValue); 260 } 261 } 262 else if (objectIdKeys != null) { 263 int len = objectIdKeys.size(); 264 265 267 Object [] keys = objectIdKeys.keySet().toArray(); 268 Arrays.sort(keys); 269 270 for (int i = 0; i < len; i++) { 271 274 builder.append(i); 277 278 Object value = objectIdKeys.get(keys[i]); 279 if (value instanceof Number ) { 281 builder.append(((Number ) value).longValue()); 282 } 283 else { 284 builder.append(value); 285 } 286 } 287 } 288 289 this.hashCode = builder.toHashCode(); 290 assert hashCode != 0 : "Generated zero hashCode"; 291 } 292 293 return hashCode; 294 } 295 296 302 public Map getReplacementIdMap() { 303 if (replacementIdMap == null) { 304 replacementIdMap = new HashMap (); 305 } 306 307 return replacementIdMap; 308 } 309 310 315 public ObjectId createReplacementId() { 316 Map newIdMap = new HashMap (getIdSnapshot()); 319 if (replacementIdMap != null) { 320 newIdMap.putAll(replacementIdMap); 321 } 322 return new ObjectId(getEntityName(), newIdMap); 323 } 324 325 330 public boolean isReplacementIdAttached() { 331 return replacementIdMap != null && !replacementIdMap.isEmpty(); 332 } 333 334 338 public String toString() { 339 340 StringBuffer buffer = new StringBuffer (); 341 342 buffer.append("<ObjectId:").append(entityName); 343 344 if (isTemporary()) { 345 buffer.append(", TEMP:"); 346 for (int i = 0; i < key.length; i++) { 347 IDUtil.appendFormattedByte(buffer, key[i]); 348 } 349 } 350 else if (singleKey != null) { 351 buffer.append(", ").append(String.valueOf(singleKey)).append("=").append( 352 singleValue); 353 } 354 else if (objectIdKeys != null) { 355 356 357 360 List keys = new ArrayList (objectIdKeys.keySet()); 361 Collections.sort(keys); 362 Iterator it = keys.iterator(); 363 while (it.hasNext()) { 364 Object key = it.next(); 365 buffer.append(", "); 366 buffer.append(String.valueOf(key)).append("=").append( 367 objectIdKeys.get(key)); 368 } 369 } 370 371 buffer.append(">"); 372 return buffer.toString(); 373 } 374 } 375 | Popular Tags |