001// Copyright 2023, 2024 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007// http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry5.plastic;
016
017/**
018 * <p>
019 * Interface that can be implemented to provide access to field values based on their name.
020 * Usually implemented with {@linkplain PlasticUtils#implementPropertyValueProvider(PlasticClass, java.util.Set)}.
021 * </p>
022 * <p>
023 * The name of its abstract method is intended to avoid clashes with other existing methods
024 * in the class.
025 * </p>
026 * @see PlasticUtils#implementPropertyValueProvider(PlasticClass, java.util.Set)
027 * @since 5.8.4
028 */
029public interface PropertyValueProvider
030{
031    /**
032     * Returns the value of a given field.
033     * @param fieldName the field name.
034     * @return the field value.
035     */
036    Object __propertyValueProvider__get(String fieldName);
037
038    /**
039     * Sets the value of a given field.
040     * @param fieldName the field name.
041     * @param value the field value.
042     * @since 5.8.7
043     */
044    void __propertyValueProvider__set(String fieldName, Object value);
045
046    /**
047     * <p>
048     * Returns the value of a given field in a given object if it belongs to a class
049     * that implements {@linkplain PropertyValueProvider}. Otherwise, it throws an exception.
050     * </p>
051     * <p>
052     * This is an utility method to avoid having to make casts very time you need to call
053     * {@linkplain #__propertyValueProvider__get(String)}.
054     * </p>
055     * @param object an object.
056     * @param fieldName the field name.
057     * @return the field value.
058     */
059    static Object get(Object object, String fieldName)
060    {
061        if (object instanceof PropertyValueProvider)
062        {
063            return ((PropertyValueProvider) object).__propertyValueProvider__get(fieldName);
064        }
065        else
066        {
067            throw new RuntimeException("Class " + object.getClass().getName() + " doesn't implement " + PropertyValueProvider.class.getSimpleName());
068        }
069    }
070    
071    /**
072     * <p>
073     * Sets the value of a given field in a given object if it belongs to a class
074     * that implements {@linkplain PropertyValueProvider}. Otherwise, it throws an exception.
075     * </p>
076     * <p>
077     * This is an utility method to avoid having to make casts very time you need to call
078     * {@linkplain #__propertyValueProvider__set(String, Object)}.
079     * </p>
080     * @param object an object.
081     * @param fieldName the field name.
082     * @param value the field value.
083     * @since 5.8.7
084     */
085    static void set(Object object, String fieldName, Object value)
086    {
087        if (object instanceof PropertyValueProvider)
088        {
089            ((PropertyValueProvider) object).__propertyValueProvider__set(fieldName, value);
090        }
091        else
092        {
093            throw new RuntimeException("Class " + object.getClass().getName() + " doesn't implement " + PropertyValueProvider.class.getSimpleName());
094        }
095    }
096    
097}