1 16 package org.apache.commons.lang.builder; 17 18 import java.lang.reflect.AccessibleObject ; 19 import java.lang.reflect.Field ; 20 import java.lang.reflect.Modifier ; 21 22 82 public class EqualsBuilder { 83 84 88 private boolean isEquals = true; 89 90 96 public EqualsBuilder() { 97 } 99 100 102 120 public static boolean reflectionEquals(Object lhs, Object rhs) { 121 return reflectionEquals(lhs, rhs, false, null); 122 } 123 124 144 public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients) { 145 return reflectionEquals(lhs, rhs, testTransients, null); 146 } 147 148 173 public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients, Class reflectUpToClass) { 174 if (lhs == rhs) { 175 return true; 176 } 177 if (lhs == null || rhs == null) { 178 return false; 179 } 180 Class lhsClass = lhs.getClass(); 185 Class rhsClass = rhs.getClass(); 186 Class testClass; 187 if (lhsClass.isInstance(rhs)) { 188 testClass = lhsClass; 189 if (!rhsClass.isInstance(lhs)) { 190 testClass = rhsClass; 192 } 193 } else if (rhsClass.isInstance(lhs)) { 194 testClass = rhsClass; 195 if (!lhsClass.isInstance(rhs)) { 196 testClass = lhsClass; 198 } 199 } else { 200 return false; 202 } 203 EqualsBuilder equalsBuilder = new EqualsBuilder(); 204 try { 205 reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients); 206 while (testClass.getSuperclass() != null && testClass != reflectUpToClass) { 207 testClass = testClass.getSuperclass(); 208 reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients); 209 } 210 } catch (IllegalArgumentException e) { 211 return false; 217 } 218 return equalsBuilder.isEquals(); 219 } 220 221 231 private static void reflectionAppend( 232 Object lhs, 233 Object rhs, 234 Class clazz, 235 EqualsBuilder builder, 236 boolean useTransients) { 237 Field [] fields = clazz.getDeclaredFields(); 238 AccessibleObject.setAccessible(fields, true); 239 for (int i = 0; i < fields.length && builder.isEquals; i++) { 240 Field f = fields[i]; 241 if ((f.getName().indexOf('$') == -1) 242 && (useTransients || !Modifier.isTransient(f.getModifiers())) 243 && (!Modifier.isStatic(f.getModifiers()))) { 244 try { 245 builder.append(f.get(lhs), f.get(rhs)); 246 } catch (IllegalAccessException e) { 247 throw new InternalError ("Unexpected IllegalAccessException"); 250 } 251 } 252 } 253 } 254 255 257 264 public EqualsBuilder appendSuper(boolean superEquals) { 265 if (isEquals == false) { 266 return this; 267 } 268 isEquals = superEquals; 269 return this; 270 } 271 272 274 282 public EqualsBuilder append(Object lhs, Object rhs) { 283 if (isEquals == false) { 284 return this; 285 } 286 if (lhs == rhs) { 287 return this; 288 } 289 if (lhs == null || rhs == null) { 290 this.setEquals(false); 291 return this; 292 } 293 Class lhsClass = lhs.getClass(); 294 if (!lhsClass.isArray()) { 295 isEquals = lhs.equals(rhs); 297 } else if (lhs.getClass() != rhs.getClass()) { 298 this.setEquals(false); 300 } 301 else if (lhs instanceof long[]) { 304 append((long[]) lhs, (long[]) rhs); 305 } else if (lhs instanceof int[]) { 306 append((int[]) lhs, (int[]) rhs); 307 } else if (lhs instanceof short[]) { 308 append((short[]) lhs, (short[]) rhs); 309 } else if (lhs instanceof char[]) { 310 append((char[]) lhs, (char[]) rhs); 311 } else if (lhs instanceof byte[]) { 312 append((byte[]) lhs, (byte[]) rhs); 313 } else if (lhs instanceof double[]) { 314 append((double[]) lhs, (double[]) rhs); 315 } else if (lhs instanceof float[]) { 316 append((float[]) lhs, (float[]) rhs); 317 } else if (lhs instanceof boolean[]) { 318 append((boolean[]) lhs, (boolean[]) rhs); 319 } else { 320 append((Object []) lhs, (Object []) rhs); 322 } 323 return this; 324 } 325 326 337 public EqualsBuilder append(long lhs, long rhs) { 338 if (isEquals == false) { 339 return this; 340 } 341 isEquals = (lhs == rhs); 342 return this; 343 } 344 345 352 public EqualsBuilder append(int lhs, int rhs) { 353 if (isEquals == false) { 354 return this; 355 } 356 isEquals = (lhs == rhs); 357 return this; 358 } 359 360 367 public EqualsBuilder append(short lhs, short rhs) { 368 if (isEquals == false) { 369 return this; 370 } 371 isEquals = (lhs == rhs); 372 return this; 373 } 374 375 382 public EqualsBuilder append(char lhs, char rhs) { 383 if (isEquals == false) { 384 return this; 385 } 386 isEquals = (lhs == rhs); 387 return this; 388 } 389 390 397 public EqualsBuilder append(byte lhs, byte rhs) { 398 if (isEquals == false) { 399 return this; 400 } 401 isEquals = (lhs == rhs); 402 return this; 403 } 404 405 418 public EqualsBuilder append(double lhs, double rhs) { 419 if (isEquals == false) { 420 return this; 421 } 422 return append(Double.doubleToLongBits(lhs), Double.doubleToLongBits(rhs)); 423 } 424 425 438 public EqualsBuilder append(float lhs, float rhs) { 439 if (isEquals == false) { 440 return this; 441 } 442 return append(Float.floatToIntBits(lhs), Float.floatToIntBits(rhs)); 443 } 444 445 452 public EqualsBuilder append(boolean lhs, boolean rhs) { 453 if (isEquals == false) { 454 return this; 455 } 456 isEquals = (lhs == rhs); 457 return this; 458 } 459 460 470 public EqualsBuilder append(Object [] lhs, Object [] rhs) { 471 if (isEquals == false) { 472 return this; 473 } 474 if (lhs == rhs) { 475 return this; 476 } 477 if (lhs == null || rhs == null) { 478 this.setEquals(false); 479 return this; 480 } 481 if (lhs.length != rhs.length) { 482 this.setEquals(false); 483 return this; 484 } 485 for (int i = 0; i < lhs.length && isEquals; ++i) { 486 append(lhs[i], rhs[i]); 487 } 488 return this; 489 } 490 491 501 public EqualsBuilder append(long[] lhs, long[] rhs) { 502 if (isEquals == false) { 503 return this; 504 } 505 if (lhs == rhs) { 506 return this; 507 } 508 if (lhs == null || rhs == null) { 509 this.setEquals(false); 510 return this; 511 } 512 if (lhs.length != rhs.length) { 513 this.setEquals(false); 514 return this; 515 } 516 for (int i = 0; i < lhs.length && isEquals; ++i) { 517 append(lhs[i], rhs[i]); 518 } 519 return this; 520 } 521 522 532 public EqualsBuilder append(int[] lhs, int[] rhs) { 533 if (isEquals == false) { 534 return this; 535 } 536 if (lhs == rhs) { 537 return this; 538 } 539 if (lhs == null || rhs == null) { 540 this.setEquals(false); 541 return this; 542 } 543 if (lhs.length != rhs.length) { 544 this.setEquals(false); 545 return this; 546 } 547 for (int i = 0; i < lhs.length && isEquals; ++i) { 548 append(lhs[i], rhs[i]); 549 } 550 return this; 551 } 552 553 563 public EqualsBuilder append(short[] lhs, short[] rhs) { 564 if (isEquals == false) { 565 return this; 566 } 567 if (lhs == rhs) { 568 return this; 569 } 570 if (lhs == null || rhs == null) { 571 this.setEquals(false); 572 return this; 573 } 574 if (lhs.length != rhs.length) { 575 this.setEquals(false); 576 return this; 577 } 578 for (int i = 0; i < lhs.length && isEquals; ++i) { 579 append(lhs[i], rhs[i]); 580 } 581 return this; 582 } 583 584 594 public EqualsBuilder append(char[] lhs, char[] rhs) { 595 if (isEquals == false) { 596 return this; 597 } 598 if (lhs == rhs) { 599 return this; 600 } 601 if (lhs == null || rhs == null) { 602 this.setEquals(false); 603 return this; 604 } 605 if (lhs.length != rhs.length) { 606 this.setEquals(false); 607 return this; 608 } 609 for (int i = 0; i < lhs.length && isEquals; ++i) { 610 append(lhs[i], rhs[i]); 611 } 612 return this; 613 } 614 615 625 public EqualsBuilder append(byte[] lhs, byte[] rhs) { 626 if (isEquals == false) { 627 return this; 628 } 629 if (lhs == rhs) { 630 return this; 631 } 632 if (lhs == null || rhs == null) { 633 this.setEquals(false); 634 return this; 635 } 636 if (lhs.length != rhs.length) { 637 this.setEquals(false); 638 return this; 639 } 640 for (int i = 0; i < lhs.length && isEquals; ++i) { 641 append(lhs[i], rhs[i]); 642 } 643 return this; 644 } 645 646 656 public EqualsBuilder append(double[] lhs, double[] rhs) { 657 if (isEquals == false) { 658 return this; 659 } 660 if (lhs == rhs) { 661 return this; 662 } 663 if (lhs == null || rhs == null) { 664 this.setEquals(false); 665 return this; 666 } 667 if (lhs.length != rhs.length) { 668 this.setEquals(false); 669 return this; 670 } 671 for (int i = 0; i < lhs.length && isEquals; ++i) { 672 append(lhs[i], rhs[i]); 673 } 674 return this; 675 } 676 677 687 public EqualsBuilder append(float[] lhs, float[] rhs) { 688 if (isEquals == false) { 689 return this; 690 } 691 if (lhs == rhs) { 692 return this; 693 } 694 if (lhs == null || rhs == null) { 695 this.setEquals(false); 696 return this; 697 } 698 if (lhs.length != rhs.length) { 699 this.setEquals(false); 700 return this; 701 } 702 for (int i = 0; i < lhs.length && isEquals; ++i) { 703 append(lhs[i], rhs[i]); 704 } 705 return this; 706 } 707 708 718 public EqualsBuilder append(boolean[] lhs, boolean[] rhs) { 719 if (isEquals == false) { 720 return this; 721 } 722 if (lhs == rhs) { 723 return this; 724 } 725 if (lhs == null || rhs == null) { 726 this.setEquals(false); 727 return this; 728 } 729 if (lhs.length != rhs.length) { 730 this.setEquals(false); 731 return this; 732 } 733 for (int i = 0; i < lhs.length && isEquals; ++i) { 734 append(lhs[i], rhs[i]); 735 } 736 return this; 737 } 738 739 745 public boolean isEquals() { 746 return this.isEquals; 747 } 748 749 755 protected void setEquals(boolean isEquals) { 756 this.isEquals = isEquals; 757 } 758 } 759 | Popular Tags |