EqualsUtil.java

  1. /**
  2.  *
  3.  * Copyright 2019-2020 Florian Schmaus.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smack.util;

  18. public final class EqualsUtil {

  19.     private EqualsUtil() {
  20.     }

  21.     public static <T> boolean equals(T thisObject, Object other, EqualsComperator<T> equalsComperator) {
  22.         if (other == null) {
  23.             return false;
  24.         }
  25.         if (thisObject == other) {
  26.             return true;
  27.         }
  28.         @SuppressWarnings("unchecked")
  29.         Class<T> thisObjectClass = (Class<T>) thisObject.getClass();
  30.         if (thisObjectClass != other.getClass()) {
  31.             return false;
  32.         }

  33.         int thisHashCode = thisObject.hashCode();
  34.         int otherHashCode = other.hashCode();
  35.         if (thisHashCode != otherHashCode) {
  36.             return false;
  37.         }

  38.         EqualsUtil.Builder equalsBuilder = new EqualsUtil.Builder();

  39.         equalsComperator.compare(equalsBuilder, thisObjectClass.cast(other));

  40.         return equalsBuilder.isEquals;
  41.     }

  42.     @FunctionalInterface
  43.     public interface EqualsComperator<T> {
  44.         void compare(EqualsUtil.Builder equalsBuilder, T other);
  45.     }

  46.     public static final class Builder {
  47.         private boolean isEquals = true;

  48.         private Builder() {
  49.         }

  50.         private void nullSafeCompare(Object left, Object right, Runnable runnable) {
  51.             if (!isEquals) {
  52.                 return;
  53.             }

  54.             if (left == right) {
  55.                 return;
  56.             }

  57.             if (left == null || right == null) {
  58.                 isEquals = false;
  59.                 return;
  60.             }

  61.             runnable.run();
  62.         }

  63.         public <O> Builder append(O left, O right) {
  64.             if (!isEquals) {
  65.                 return this;
  66.             }

  67.             if (left == right) {
  68.                 return this;
  69.             }

  70.             if (left == null || right == null) {
  71.                 isEquals = false;
  72.                 return this;
  73.             }

  74.             isEquals = left.equals(right);
  75.             return this;
  76.         }

  77.         public Builder append(boolean left, boolean right) {
  78.             if (!isEquals) {
  79.                 return this;
  80.             }

  81.             isEquals = left == right;
  82.             return this;
  83.         }

  84.         public Builder append(boolean[] left, boolean[] right) {
  85.             nullSafeCompare(left, right, () -> {
  86.                 if (left.length != right.length) {
  87.                     isEquals = false;
  88.                     return;
  89.                 }
  90.                 for (int i = 0; i < left.length && isEquals; i++) {
  91.                     append(left[i], right[i]);
  92.                 }
  93.             });
  94.             return this;
  95.         }

  96.         public Builder append(byte left, byte right) {
  97.             if (!isEquals) {
  98.                 return this;
  99.             }

  100.             isEquals = left == right;
  101.             return this;
  102.         }

  103.         public Builder append(byte[] left, byte[] right) {
  104.             nullSafeCompare(left, right, () -> {
  105.                 if (left.length != right.length) {
  106.                     isEquals = false;
  107.                     return;
  108.                 }
  109.                 for (int i = 0; i < left.length && isEquals; i++) {
  110.                     append(left[i], right[i]);
  111.                 }
  112.             });
  113.             return this;
  114.         }

  115.         public Builder append(char left, char right) {
  116.             if (!isEquals) {
  117.                 return this;
  118.             }

  119.             isEquals = left == right;
  120.             return this;
  121.         }

  122.         public Builder append(char[] left, char[] right) {
  123.             nullSafeCompare(left, right, () -> {
  124.                 if (left.length != right.length) {
  125.                     isEquals = false;
  126.                     return;
  127.                 }
  128.                 for (int i = 0; i < left.length && isEquals; i++) {
  129.                     append(left[i], right[i]);
  130.                 }
  131.             });
  132.             return this;
  133.         }

  134.         public Builder append(double left, double right) {
  135.             if (!isEquals) {
  136.                 return this;
  137.             }

  138.             return append(Double.doubleToLongBits(left), Double.doubleToLongBits(right));
  139.         }

  140.         public Builder append(double[] left, double[] right) {
  141.             nullSafeCompare(left, right, () -> {
  142.                 if (left.length != right.length) {
  143.                     isEquals = false;
  144.                     return;
  145.                 }
  146.                 for (int i = 0; i < left.length && isEquals; i++) {
  147.                     append(left[i], right[i]);
  148.                 }
  149.             });
  150.             return this;
  151.         }

  152.         public Builder append(float left, float right) {
  153.             if (!isEquals) {
  154.                 return this;
  155.             }

  156.             return append(Float.floatToIntBits(left), Float.floatToIntBits(right));
  157.         }

  158.         public Builder append(float[] left, float[] right) {
  159.             nullSafeCompare(left, right, () -> {
  160.                 if (left.length != right.length) {
  161.                     isEquals = false;
  162.                     return;
  163.                 }
  164.                 for (int i = 0; i < left.length && isEquals; i++) {
  165.                     append(left[i], right[i]);
  166.                 }
  167.             });
  168.             return this;
  169.         }

  170.         public Builder append(int left, int right) {
  171.             if (!isEquals) {
  172.                 return this;
  173.             }

  174.             isEquals = left == right;
  175.             return this;
  176.         }

  177.         public Builder append(int[] left, int[] right) {
  178.             nullSafeCompare(left, right, () -> {
  179.                 if (left.length != right.length) {
  180.                     isEquals = false;
  181.                     return;
  182.                 }
  183.                 for (int i = 0; i < left.length && isEquals; i++) {
  184.                     append(left[i], right[i]);
  185.                 }
  186.             });
  187.             return this;
  188.         }

  189.         public Builder append(long left, long right) {
  190.             if (!isEquals) {
  191.                 return this;
  192.             }

  193.             isEquals = left == right;
  194.             return this;
  195.         }

  196.         public Builder append(long[] left, long[] right) {
  197.             nullSafeCompare(left, right, () -> {
  198.                 if (left.length != right.length) {
  199.                     isEquals = false;
  200.                     return;
  201.                 }
  202.                 for (int i = 0; i < left.length && isEquals; i++) {
  203.                     append(left[i], right[i]);
  204.                 }
  205.             });
  206.             return this;
  207.         }
  208.     }

  209. }