示例#1
0
  /**
   * If a comparison between two AutoBeans is currently pending, this method will skip their
   * comparison.
   */
  private static boolean sameOrEquals(
      AutoBean<?> value, AutoBean<?> otherValue, Map<PendingComparison, Comparison> pending) {
    if (value == otherValue) {
      // Simple case
      return true;
    } else if (!value.getType().equals(otherValue.getType())) {
      // Beans of different types
      return false;
    }

    /*
     * The PendingComparison key allows us to break reference cycles when
     * crawling the graph. Since the entire operation is essentially a
     * concatenated && operation, it's ok to speculatively return true for
     * repeated a.equals(b) tests.
     */
    PendingComparison key = new PendingComparison(value, otherValue);
    Comparison previous = pending.get(key);
    if (previous == null) {
      // Prevent the same comparison from being made
      pending.put(key, Comparison.PENDING);

      // Compare each property
      Map<String, Object> beanProperties = AutoBeanUtils.getAllProperties(value);
      Map<String, Object> otherProperties = AutoBeanUtils.getAllProperties(otherValue);
      for (Map.Entry<String, Object> entry : beanProperties.entrySet()) {
        Object property = entry.getValue();
        Object otherProperty = otherProperties.get(entry.getKey());
        if (!sameOrEquals(property, otherProperty, pending)) {
          pending.put(key, Comparison.FALSE);
          return false;
        }
      }
      pending.put(key, Comparison.TRUE);
      return true;
    } else {
      // Return true for TRUE or PENDING
      return !Comparison.FALSE.equals(previous);
    }
  }