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

io.ultreia.java4all.bean.definition.JavaBeanDefinition Maven / Gradle / Ivy

package io.ultreia.java4all.bean.definition;

/*-
 * #%L
 * Java Beans extends by Ultreia.io
 * %%
 * Copyright (C) 2018 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import io.ultreia.java4all.bean.JavaBean;
import io.ultreia.java4all.bean.JavaBeanComparatorBuilder;
import io.ultreia.java4all.bean.JavaBeanInstanceBuilder;
import io.ultreia.java4all.bean.JavaBeanPredicate;

import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by tchemit on 07/01/2018.
 *
 * @author Tony Chemit - [email protected]
 */
public interface JavaBeanDefinition {

    /**
     * Ge the set of accepted types using this definition.
     * This means that the method {@link JavaBeanDefinitionStore#getDefinition(Class)} will give this instance of definition
     * for any types of this set.
     *
     * @return set of accepted types using this definition
     */
    Set> types();

    /**
     * @return dictionary of all properties indexed by their name
     */
    Map> properties();

    /**
     * @return stream of readable properties
     */
    default Stream> readProperties() {
        return properties().values().stream().filter(JavaBeanPropertyDefinition::canRead);
    }

    /**
     * @return stream of writable properties
     */
    default Stream> writeProperties() {
        return properties().values().stream().filter(JavaBeanPropertyDefinition::canWrite);
    }


    /**
     * @return stream of readable and writable properties
     */
    default Stream> readAndWriteProperties() {
        return properties().values().stream().filter(JavaBeanPropertyDefinition::canReadAndWrite);
    }

    default  V get(String propertyName, JavaBean source) {
        JavaBeanPropertyDefinition readDefinition = readProperty(propertyName);
        return readDefinition.get(source);
    }

    /**
     * Get a property given his name.
     *
     * @param propertyName name of property to seek
     * @param           type of the java bean
     * @param           type of the property
     * @return the property
     * @throws NullPointerException if no property found
     */
    @SuppressWarnings("unchecked")
    default  JavaBeanPropertyDefinition property(String propertyName) {
        return (JavaBeanPropertyDefinition) Objects.requireNonNull(properties().get(propertyName), String.format("Can't find property %s.", propertyName));
    }

    default  void set(String propertyName, JavaBean target, V propertyValue) {
        JavaBeanPropertyDefinition writeDefinition = writeProperty(propertyName);
        writeDefinition.set(target, propertyValue);
    }

    default  void copy(String propertyName, JavaBean source, JavaBean target) {
        boolean sameDefinition = target.javaBeanDefinition().equals(this);
        if (sameDefinition) {
            JavaBeanPropertyDefinition readAndWriteDefinition = readAndWriteProperty(propertyName);
            readAndWriteDefinition.copy(source, target);
        } else {
            JavaBeanPropertyDefinition readDefinition = readProperty(propertyName);
            V value = readDefinition.get(source);
            target.set(propertyName, value);
        }
    }

    @SuppressWarnings("unchecked")
    default void copy(JavaBean source, JavaBean target) {
        boolean sameDefinition = target.javaBeanDefinition().equals(this);
        if (sameDefinition) {
            readAndWriteProperties().forEach(propertyDefinition ->
                    ((JavaBeanPropertyDefinition) propertyDefinition).copy(source, target)
            );
        } else {
            Map> targetProperties = target.javaBeanDefinition().properties();
            for (JavaBeanPropertyDefinition readDefinition : readProperties().collect(Collectors.toSet())) {
                JavaBeanPropertyDefinition writeDefinition = targetProperties.get(readDefinition.propertyName());
                if (writeDefinition != null && writeDefinition.canWrite()) {
                    Object value = readDefinition.get(source);
                    writeDefinition.set(target, value);
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    default void clear(JavaBean target) {
        writeProperties().forEach(propertyDefinition ->
                ((JavaBeanPropertyDefinition) propertyDefinition).clear(target)
        );
    }

    /**
     * Get a readable property given his name.
     *
     * @param propertyName name of property to seek
     * @param           type of the java bean
     * @param           type of the property
     * @return the property
     * @throws NullPointerException     if no property found
     * @throws IllegalArgumentException if property is not readable
     */
    default  JavaBeanPropertyDefinition readProperty(String propertyName) {
        return this.property(propertyName).checkCanRead();
    }

    /**
     * Get a writable property given his name.
     *
     * @param propertyName name of property to seek
     * @param           type of the java bean
     * @param           type of the property
     * @return the property
     * @throws NullPointerException     if no property found
     * @throws IllegalArgumentException if property is not writable
     */
    default  JavaBeanPropertyDefinition writeProperty(String propertyName) {
        return this.property(propertyName).checkCanWrite();
    }

    /**
     * Get a readable and writable property given his name.
     *
     * @param propertyName name of property to seek
     * @param           type of the java bean
     * @param           type of the property
     * @return the property
     * @throws NullPointerException     if no property found
     * @throws IllegalArgumentException if property is not readable, nor writable
     */
    default  JavaBeanPropertyDefinition readAndWriteProperty(String propertyName) {
        return this.property(propertyName).checkCanRead().checkCanWrite();
    }

    default JavaBeanPredicate predicateBuilder() {
        throw new UnsupportedOperationException();
    }

    default JavaBeanComparatorBuilder comparatorBuilder() {
        throw new UnsupportedOperationException();
    }

    default JavaBeanInstanceBuilder instanceBuilder() {
        throw new UnsupportedOperationException();
    }

     O newInstance();

//    default  JavaBeanStream streamBuilder(Collection elements) {
//        throw new UnsupportedOperationException();
//    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy