001/*
002 * Copyright 2023 the original author or authors.
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * https://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.tools.property;
017
018import java.io.Serializable;
019import java.lang.reflect.Modifier;
020
021import de.cuioss.tools.reflect.MoreReflection;
022
023/**
024 * Members of this enum define the way the corresponding property is subject to
025 * the contracts regarding the canonical {@link Object} methods like
026 * {@link Object#equals(Object)}, {@link Object#hashCode()} and
027 * {@link Object#toString()} and the {@link Serializable} contract
028 *
029 * @author Oliver Wolff
030 */
031public enum PropertyMemberInfo {
032
033    /**
034     * Defines a default property contract, saying it is not transient and defines
035     * the Object-identity, {@link Object#equals(Object)}, {@link Object#hashCode()}
036     * and {@link Object#toString()}
037     */
038    DEFAULT,
039
040    /**
041     * Defines a property that is not transient, and is not part of the
042     * object-identity and should therefore be ignored in the methods
043     * {@link Object#equals(Object)}, {@link Object#hashCode()}
044     */
045    NO_IDENTITY,
046
047    /**
048     * Defines a transient property that is not part of the object-identity and
049     * should therefore be ignored in the methods {@link Object#equals(Object)} and
050     * the serialization.
051     */
052    TRANSIENT,
053
054    /** The actual state can not be defined. */
055    UNDEFINED;
056
057    /**
058     * Resolves {@link PropertyMemberInfo} for a given property with
059     * {@link MoreReflection}. This method can solely distinguish between the states
060     * {@link #UNDEFINED}, {@link #DEFAULT} and {@link #TRANSIENT}.
061     * {@link #NO_IDENTITY} must be defined from the caller if necessary;
062     *
063     * @param beanType     to be checked, must not be null
064     * @param propertyName to be checked, must not be null
065     * @return the corresponding {@link PropertyReadWrite} for a given property
066     */
067    public static PropertyMemberInfo resolveForBean(final Class<?> beanType, final String propertyName) {
068        var fieldOption = MoreReflection.accessField(beanType, propertyName);
069        if (fieldOption.isEmpty()) {
070            return UNDEFINED;
071        }
072        if (Modifier.isTransient(fieldOption.get().getModifiers())) {
073            return PropertyMemberInfo.TRANSIENT;
074        }
075        return PropertyMemberInfo.DEFAULT;
076    }
077}