1 16 17 package org.springframework.beans.factory.config; 18 19 import java.util.Collections ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.LinkedList ; 23 import java.util.List ; 24 import java.util.Map ; 25 import java.util.Set ; 26 27 import org.springframework.beans.BeanMetadataElement; 28 import org.springframework.beans.Mergeable; 29 import org.springframework.util.Assert; 30 import org.springframework.util.ClassUtils; 31 import org.springframework.util.ObjectUtils; 32 33 43 public class ConstructorArgumentValues { 44 45 private final Map indexedArgumentValues = new HashMap (); 46 47 private final List genericArgumentValues = new LinkedList (); 48 49 50 53 public ConstructorArgumentValues() { 54 } 55 56 60 public ConstructorArgumentValues(ConstructorArgumentValues original) { 61 addArgumentValues(original); 62 } 63 64 71 public void addArgumentValues(ConstructorArgumentValues other) { 72 if (other != null) { 73 for (Iterator it = other.indexedArgumentValues.entrySet().iterator(); it.hasNext();) { 74 Map.Entry entry = (Map.Entry ) it.next(); 75 ValueHolder valueHolder = (ValueHolder) entry.getValue(); 76 addOrMergeIndexedArgumentValue(entry.getKey(), valueHolder.copy()); 77 } 78 for (Iterator it = other.genericArgumentValues.iterator(); it.hasNext();) { 79 ValueHolder valueHolder = (ValueHolder) it.next(); 80 if (!this.genericArgumentValues.contains(valueHolder)) { 81 this.genericArgumentValues.add(valueHolder.copy()); 82 } 83 } 84 } 85 } 86 87 88 93 public void addIndexedArgumentValue(int index, Object value) { 94 addIndexedArgumentValue(index, new ValueHolder(value)); 95 } 96 97 103 public void addIndexedArgumentValue(int index, Object value, String type) { 104 addIndexedArgumentValue(index, new ValueHolder(value, type)); 105 } 106 107 112 public void addIndexedArgumentValue(int index, ValueHolder newValue) { 113 Assert.isTrue(index >= 0, "Index must not be negative"); 114 Assert.notNull(newValue, "ValueHolder must not be null"); 115 addOrMergeIndexedArgumentValue(new Integer (index), newValue); 116 } 117 118 125 private void addOrMergeIndexedArgumentValue(Object key, ValueHolder newValue) { 126 ValueHolder currentValue = (ValueHolder) this.indexedArgumentValues.get(key); 127 if (currentValue != null && newValue.getValue() instanceof Mergeable) { 128 Mergeable mergeable = (Mergeable) newValue.getValue(); 129 if (mergeable.isMergeEnabled()) { 130 newValue.setValue(mergeable.merge(currentValue.getValue())); 131 } 132 } 133 this.indexedArgumentValues.put(key, newValue); 134 } 135 136 143 public ValueHolder getIndexedArgumentValue(int index, Class requiredType) { 144 Assert.isTrue(index >= 0, "Index must not be negative"); 145 ValueHolder valueHolder = (ValueHolder) this.indexedArgumentValues.get(new Integer (index)); 146 if (valueHolder != null) { 147 if (valueHolder.getType() == null || 148 (requiredType != null && requiredType.getName().equals(valueHolder.getType()))) { 149 return valueHolder; 150 } 151 } 152 return null; 153 } 154 155 160 public Map getIndexedArgumentValues() { 161 return Collections.unmodifiableMap(this.indexedArgumentValues); 162 } 163 164 165 171 public void addGenericArgumentValue(Object value) { 172 this.genericArgumentValues.add(new ValueHolder(value)); 173 } 174 175 182 public void addGenericArgumentValue(Object value, String type) { 183 this.genericArgumentValues.add(new ValueHolder(value, type)); 184 } 185 186 195 public void addGenericArgumentValue(ValueHolder newValue) { 196 Assert.notNull(newValue, "ValueHolder must not be null"); 197 if (!this.genericArgumentValues.contains(newValue)) { 198 this.genericArgumentValues.add(newValue); 199 } 200 } 201 202 208 public ValueHolder getGenericArgumentValue(Class requiredType) { 209 return getGenericArgumentValue(requiredType, null); 210 } 211 212 222 public ValueHolder getGenericArgumentValue(Class requiredType, Set usedValueHolders) { 223 for (Iterator it = this.genericArgumentValues.iterator(); it.hasNext();) { 224 ValueHolder valueHolder = (ValueHolder) it.next(); 225 if (usedValueHolders == null || !usedValueHolders.contains(valueHolder)) { 226 if (requiredType != null) { 227 if (valueHolder.getType() != null) { 229 if (valueHolder.getType().equals(requiredType.getName())) { 230 return valueHolder; 231 } 232 } 233 else if (ClassUtils.isAssignableValue(requiredType, valueHolder.getValue())) { 234 return valueHolder; 235 } 236 } 237 else { 238 if (valueHolder.getType() == null) { 240 return valueHolder; 241 } 242 } 243 } 244 } 245 return null; 246 } 247 248 253 public List getGenericArgumentValues() { 254 return Collections.unmodifiableList(this.genericArgumentValues); 255 } 256 257 258 265 public ValueHolder getArgumentValue(int index, Class requiredType) { 266 return getArgumentValue(index, requiredType, null); 267 } 268 269 281 public ValueHolder getArgumentValue(int index, Class requiredType, Set usedValueHolders) { 282 Assert.isTrue(index >= 0, "Index must not be negative"); 283 ValueHolder valueHolder = getIndexedArgumentValue(index, requiredType); 284 if (valueHolder == null) { 285 valueHolder = getGenericArgumentValue(requiredType, usedValueHolders); 286 } 287 return valueHolder; 288 } 289 290 294 public int getArgumentCount() { 295 return (this.indexedArgumentValues.size() + this.genericArgumentValues.size()); 296 } 297 298 302 public boolean isEmpty() { 303 return (this.indexedArgumentValues.isEmpty() && this.genericArgumentValues.isEmpty()); 304 } 305 306 309 public void clear() { 310 this.indexedArgumentValues.clear(); 311 this.genericArgumentValues.clear(); 312 } 313 314 315 public boolean equals(Object other) { 316 if (this == other) { 317 return true; 318 } 319 if (!(other instanceof ConstructorArgumentValues)) { 320 return false; 321 } 322 ConstructorArgumentValues that = (ConstructorArgumentValues) other; 323 if (this.genericArgumentValues.size() != that.genericArgumentValues.size() || 324 this.indexedArgumentValues.size() != that.indexedArgumentValues.size()) { 325 return false; 326 } 327 Iterator it1 = this.genericArgumentValues.iterator(); 328 Iterator it2 = that.genericArgumentValues.iterator(); 329 while (it1.hasNext() && it2.hasNext()) { 330 ValueHolder vh1 = (ValueHolder) it1.next(); 331 ValueHolder vh2 = (ValueHolder) it2.next(); 332 if (!vh1.contentEquals(vh2)) { 333 return false; 334 } 335 } 336 for (Iterator it = this.indexedArgumentValues.entrySet().iterator(); it.hasNext();) { 337 Map.Entry entry = (Map.Entry ) it.next(); 338 ValueHolder vh1 = (ValueHolder) entry.getValue(); 339 ValueHolder vh2 = (ValueHolder) that.indexedArgumentValues.get(entry.getKey()); 340 if (!vh1.contentEquals(vh2)) { 341 return false; 342 } 343 } 344 return true; 345 } 346 347 public int hashCode() { 348 int hashCode = 7; 349 for (Iterator it = this.genericArgumentValues.iterator(); it.hasNext();) { 350 ValueHolder valueHolder = (ValueHolder) it.next(); 351 hashCode = 31 * hashCode + valueHolder.contentHashCode(); 352 } 353 hashCode = 29 * hashCode; 354 for (Iterator it = this.indexedArgumentValues.entrySet().iterator(); it.hasNext();) { 355 Map.Entry entry = (Map.Entry ) it.next(); 356 Integer key = (Integer ) entry.getKey(); 357 ValueHolder value = (ValueHolder) entry.getValue(); 358 hashCode = 31 * hashCode + (value.contentHashCode() ^ key.hashCode()); 359 } 360 return hashCode; 361 } 362 363 364 368 public static class ValueHolder implements BeanMetadataElement { 369 370 private Object value; 371 372 private String type; 373 374 private Object source; 375 376 380 public ValueHolder(Object value) { 381 this.value = value; 382 } 383 384 389 public ValueHolder(Object value, String type) { 390 this.value = value; 391 this.type = type; 392 } 393 394 400 public void setValue(Object value) { 401 this.value = value; 402 } 403 404 407 public Object getValue() { 408 return this.value; 409 } 410 411 417 public void setType(String type) { 418 this.type = type; 419 } 420 421 424 public String getType() { 425 return this.type; 426 } 427 428 432 public void setSource(Object source) { 433 this.source = source; 434 } 435 436 public Object getSource() { 437 return this.source; 438 } 439 440 447 private boolean contentEquals(ValueHolder other) { 448 return (this == other || 449 (ObjectUtils.nullSafeEquals(this.value, other.value) && ObjectUtils.nullSafeEquals(this.type, other.type))); 450 } 451 452 458 private int contentHashCode() { 459 return ObjectUtils.nullSafeHashCode(this.value) * 29 + ObjectUtils.nullSafeHashCode(this.type); 460 } 461 462 466 public ValueHolder copy() { 467 ValueHolder copy = new ValueHolder(this.value, this.type); 468 copy.setSource(this.source); 469 return copy; 470 } 471 } 472 473 } 474 | Popular Tags |