001package io.cui.tools.property;
002
003import java.io.Serializable;
004import java.lang.reflect.Modifier;
005
006import io.cui.tools.reflect.MoreReflection;
007
008/**
009 * Members of this enum define the way the corresponding property is subject to the contracts
010 * regarding the canonical {@link Object} methods like {@link Object#equals(Object)},
011 * {@link Object#hashCode()} and {@link Object#toString()} and the {@link Serializable} contract
012 *
013 * @author Oliver Wolff
014 */
015public enum PropertyMemberInfo {
016
017    /**
018     * Defines a default property contract, saying it is not transient and defines the
019     * Object-identity, {@link Object#equals(Object)},
020     * {@link Object#hashCode()} and {@link Object#toString()}
021     */
022    DEFAULT,
023
024    /**
025     * Defines a property that is not transient, and is not part of the object-identity and should
026     * therefore be ignored in the methods {@link Object#equals(Object)},
027     * {@link Object#hashCode()}
028     */
029    NO_IDENTITY,
030
031    /**
032     * Defines a transient property that is not part of the object-identity and should
033     * therefore be ignored in the methods {@link Object#equals(Object)} and the serialization.
034     */
035    TRANSIENT,
036
037    /** The actual state can not be defined. */
038    UNDEFINED;
039
040    /**
041     * Resolves {@link PropertyMemberInfo} for a given property with {@link MoreReflection}. This
042     * method can solely distinguish between the states {@link #UNDEFINED}, {@link #DEFAULT} and
043     * {@link #TRANSIENT}. {@link #NO_IDENTITY} must be defined from the caller if necessary;
044     *
045     * @param beanType to be checked, must not be null
046     * @param propertyName to be checked, must not be null
047     * @return the corresponding {@link PropertyReadWrite} for a given property
048     */
049    public static PropertyMemberInfo resolveForBean(final Class<?> beanType, final String propertyName) {
050        var fieldOption = MoreReflection.accessField(beanType, propertyName);
051        if (!fieldOption.isPresent()) {
052            return UNDEFINED;
053        }
054        if (Modifier.isTransient(fieldOption.get().getModifiers())) {
055            return PropertyMemberInfo.TRANSIENT;
056        }
057        return PropertyMemberInfo.DEFAULT;
058    }
059}