All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pojomatic.Pojomator Maven / Gradle / Ivy

package org.pojomatic;

import java.util.Arrays;
import java.util.List;

import org.pojomatic.annotations.OverridesEquals;
import org.pojomatic.annotations.PojomaticPolicy;
import org.pojomatic.annotations.Property;
import org.pojomatic.annotations.SubclassCannotOverrideEquals;
import org.pojomatic.diff.Differences;
import org.pojomatic.formatter.DefaultPojoFormatter;
import org.pojomatic.formatter.DefaultPropertyFormatter;
import org.pojomatic.formatter.PojoFormatter;
import org.pojomatic.formatter.PropertyFormatter;

/**
 * A provider of the three standard {@code Object} methods,
 * {@link Object#equals(Object)}, {@link Object#hashCode()} and {@link Object#toString()}, as
 * well as a useful method to aid in debugging, {@link #doDiff(Object, Object)}.
 *
 * @param  the class this {@code Pojomator} is generated for.
 */
public interface Pojomator {

  /**
   * Compute the hashCode for a given instance of {@code T}.
   * This is done by computing the hashCode of each property which has a {@link PojomaticPolicy} of
   * {@link PojomaticPolicy#HASHCODE_EQUALS HASHCODE_EQUALS} or {@link PojomaticPolicy#ALL ALL}
   * (using 0 when the property is null), and combining them in a fashion similar to that of
   * {@link List#hashCode()}.
   *
   * @param instance the instance to compute the hashCode for - must not be {@code null}
   * @return the hashCode of {@code instance}
   * @throws NullPointerException if {@code instance} is {@code null}
   * @see Object#hashCode()
   */
  int doHashCode(T instance);

  /**
   * Compute the {@code toString} representation for a given instance of {@code T}.
   * 

* The format used depends on the * {@link PojoFormatter} used for the POJO, and the {@link PropertyFormatter} of each property. *

* For example, suppose a class {@code Person} has properties {@code firstName} and * {@code lastName} which are included in its {@code String} representation. * No {@code PojoFormatter} or {@code PropertyFormatter} are specified, so the defaults are used. * In particular, instances of {@code DefaultPropertyFormatter} will be created for * {@code firstName} and {@code lastName} (referred to here as {@code firstNameFormatter} and * {@code lastNameFormatter}, respectively). Let {@code firstNameProperty} and * {@code lastNameProperty} refer to the instances of {@link PropertyElement} referring to the * properties {@code firstName} and {@code lastName} respectively. *

*

* For a non-null {@code Person} instance, the {@code String} representation will be created by * creating an instance of {@code DefaultPojoFormatter} for the {@code Person} class (referred to * here as {@code personFormatter}), and then concatenating the results of following: *

    *
  1. {@link DefaultPojoFormatter#getToStringPrefix(Class) personFormatter.getToStringPrefix(Person.class)}
  2. *
  3. {@link DefaultPojoFormatter#getPropertyPrefix(PropertyElement) personFormatter.getPropertyPrefix(firstNameProperty)}
  4. *
  5. {@link DefaultPropertyFormatter#format(Object) firstNameFormatter.format(firstName)}
  6. *
  7. {@link DefaultPojoFormatter#getPropertySuffix(PropertyElement) personFormatter.getPropertySuffix(firstNameProperty)}
  8. *
  9. {@link DefaultPojoFormatter#getPropertyPrefix(PropertyElement) personFormatter.getPropertyPrefix(lastNameProperty)}
  10. *
  11. {@link DefaultPropertyFormatter#format(Object) lastNameFormatter.format(lastName)}
  12. *
  13. {@link DefaultPojoFormatter#getPropertySuffix(PropertyElement) personFormatter.getPropertySuffix(lasttNameProperty)}
  14. *
  15. {@link DefaultPojoFormatter#getToStringSuffix(Class) personFormatter.getToStringSuffix(Person.class)}
  16. *
*

* * @param instance the instance to compute the {@code toString} representation for - must not be {@code null} * @return the {@code toString} representation of {@code instance} * @throws NullPointerException if {@code instance} is {@code null} * @see Object#toString() * @see Property#name() */ String doToString(T instance); /** * Compute whether {@code instance} and {@code other} are equal to each other in the sense of * {@code Object}'s {@link Object#equals(Object) equals} method. For two instances to be * considered equal, the first requirement is that their classes must be compatible for equality, * as described in the documentation for {@link #isCompatibleForEquality(Class)}. *

*

* More precisely, if {@code other} is null, this method returns {@code false}. Otherwise, if * {@link #isCompatibleForEquality(Class) isCompatibleForEquals(other.getClass())} would return * false, then this method will return false. Otherwise, this method will return true provided * that each property of {@code instance} which has a {@code PojomaticPolicy} other than * {@code TO_STRING} or {@code NONE} is equal to the corresponding property of {@code other} in * the following sense: *

    *
  • Both are {@code null}, or
  • *
  • Both are reference-equals (==) to each other, or
  • *
  • Both are primitive of the same type, and equal to each other, or
  • *
  • Both are of array type, with matching primitive component types, and the corresponding * {@code} equals method of {@link Arrays} returns true, or
  • *
  • Both are of array type with non-primitive component types, and * {@link Arrays#deepEquals(Object[], Object[])} returns true, or
  • *
  • The property {@code p} in {@code instance} is an object not of array type, and {@code * instanceP.equals(otherP)} returns true. *
*

* @param instance the instance to test against - must not be {@code null} * @param other the instance to test * @return {@code true} if {@code instance} should be considered equal to {@code other}, and * {@code false} otherwise. * @throws NullPointerException if {@code instance} is {@code null} * @see Object#equals(Object) */ boolean doEquals(T instance, Object other); /** * Compute whether {@code otherClass} is compatible for equality with {@code T}. * Classes {@code A} and {@code B} are compatible for equality if * they share a common superclass {@code C}, and for every class {@code D} which * is a proper subclass of {@code C} and a superclass of {@code A} or {@code B} (including * the classes {@code A} and {@code B} themselves), the following hold: *
    *
  • {@code D} has not added additional properties for inclusion in the {@code equals} calculation, and
  • *
  • {@code D} has not been annotated with {@link OverridesEquals}
  • *
* If {@code T} is an interface or is annotated with {@link SubclassCannotOverrideEquals}, * then all subclasses of {@code T} are automatically assumed by {@code T}'s {@code Pojomator} * to be compatible for equals with each other and with {@code T}. Note that in this case. * to add an {@link OverridesEquals} annotation or additional * properties for inclusion in {@code equals} to a subclass of {@code T} will * result in a violation of the contract for {@link Object#equals(Object)}. * @param otherClass the class to check for compatibility for equality with {@code T} * @return {@code true} if {@code otherClass} is compatible for equality with {@code T}, and * {@code false} otherwise. */ boolean isCompatibleForEquality(Class otherClass); /** * Compute the differences between {@code instance} and {@code other} among the properties * examined by {@link #doEquals(Object, Object)}. Assuming that {@code instance} and {@code other} * are both non-null and have types which are compatible for equals, it is guaranteed that invoking * {@link Differences#areEqual()} on the returned object will return true iff * {@code instance.equals(other)}. * * @param instance the instance to diff against * @param other the instance to diff * @return the differences between {@code instance} and {@code other} * among the properties examined by {@link #doEquals(Object, Object)}. * @throws NullPointerException if {@code instance} or {@code other} is null * (this behavior may change in future releases). * @throws IllegalArgumentException the type of {@code instance} or of {@code other} is not a * class which is compatible for equality with {@code T} * (this behavior may change in future releases). * @see #doEquals(Object, Object) */ Differences doDiff(T instance, T other); /** * Return a simple String representation of this Pojomator. This is meant to aid in debugging * which properties are being used for which purposes. The contents and format of this * representation are subject to change. * * @return a simple String representation of this Pojomator. */ @Override public String toString(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy