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

nl.vpro.domain.TextualObjectUpdate Maven / Gradle / Ivy

Go to download

The basic domain classes for 'media', the core of POMS. Also, the 'update' XML bindings for it. It also contains some closely related domain classes like the enum to contain NICAM kijkwijzer settings.

There is a newer version: 8.3.1
Show newest version
package nl.vpro.domain;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Supplier;

import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import com.fasterxml.jackson.annotation.JsonIgnore;

import nl.vpro.domain.media.support.OwnerType;
import nl.vpro.domain.media.support.TextualType;
import nl.vpro.i18n.Locales;

/**
 * An object that has titles and descriptions, which are typed, but not necessary owned (unlike {@link TextualObject}).
 * This means that the object generally is used to update 'TextualObjects', since the user updating is associated with only one {@link OwnerType}.
 *
 * @param  The type of 'titles' in this object.
 * @param  The type of 'descriptions'.
 * @param  The type of {@link #self()} which is returned by several setters, so they can easily be chained
 * @author Michiel Meeuwissen
 * @since 5.3
 */
public interface TextualObjectUpdate> {

    /**
     * Describes in which language the contained text objects are. This defaults to {@link Locales#DUTCH}.
     */
    default Locale getLanguage() {
        return Locales.DUTCH;
    }

    /**
     * How to create an instance of a title. This makes a lot of default methods possible.
     *
     * @since 5.5
     */
    BiFunction getTitleCreator();

    default TO addTitle(String title, @NonNull TextualType type) {
        if (getTitles() == null) {
            setTitles(new TreeSet<>());
        }
        T created = getTitleCreator().apply(title, type);
        boolean added = getTitles().add(created);
        return self();
    }


    /**
     * Sets title if already set, otherwise {@link #addTitle(String, TextualType)}
     * @since 5.11
     */
    default void setTitle(String title, @NonNull TextualType type) {
        if (getTitles() != null) {
            for (T t : getTitles()) {
                if (t.getType() == type) {
                    t.set(title);
                    return;
                }
            }
        }
        addTitle(title, type);
    }

    /**
     * Updates a title with a {@link Supplier}, if at least the given supplier is not null.
     */
    default TO setTitle(@Nullable Supplier up, @NonNull TextualType type) {
        if (up != null) {
            setTitle(up.get(), type);
        }
        return self();
    }


    SortedSet getTitles();

    void setTitles(SortedSet titles);


    /**
     * Default implementation based on {@link #getTitles}, you may want to override this, if getTitles may modify
     * the object (it is e.g. required by jaxb that this will never return null
     */
    default boolean hasTitles() {
        return getTitles() != null && getTitles().size() > 0;
    }

    default TO addTitle(T title) {
        if (getTitles() == null) {
            setTitles(new TreeSet<>());
        }
        TextualObjects.addOrUpdate(getTitles(), title);
        return self();
    }

    default boolean removeTitle(T title) {
        return hasTitles() && getTitles().remove(title);
    }

    @SuppressWarnings("unchecked")
    default TO self() {
        return (TO) this;
    }


    default T findTitle(@NonNull TextualType type) {
        if (hasTitles()) {
            for (T title : getTitles()) {
                if (type == title.getType()) {
                    return title;
                }
            }
        }
        return null;
    }

    @JsonIgnore
    default String getMainTitle() {
        return TextualObjects.get(getTitles(), TextualType.MAIN);
    }


    default void setMainTitle(String title) {
        setTitle(title, TextualType.MAIN);
    }


    /**
     * Retrieves the first sub- or episode title. MIS distributes episode
     * titles. For internal use this episode title is handled as a subtitle.
     *
     * @return - the first subtitle
     */
    @JsonIgnore
    default String getSubTitle() {
        return TextualObjects.get(getTitles(), TextualType.SUB);
    }

    @JsonIgnore
    default String getShortTitle() {
        return TextualObjects.get(getTitles(), TextualType.SHORT);
    }

    @JsonIgnore
    default String getOriginalTitle() {
        return TextualObjects.get(getTitles(), TextualType.ORIGINAL);
    }

    @JsonIgnore
    default String getWorkTitle() {
        return TextualObjects.get(getTitles(), TextualType.WORK);
    }

    /**
     * Return the 'lexicographic title'. This is the title where the object normally would be sorted on.
     * This defaults to {@link #getMainTitle()} if no explicit value was set. If an explicit value is set, it may
     * e.g. be the same as {@link #getMainTitle()} but with leading articles ommitted.
     */
    @JsonIgnore
    default String getLexicoTitle() {
        return TextualObjects.getOptional(getTitles(), TextualType.LEXICO).orElse(getMainTitle());
    }

    /**
     * @since 2.1
     */
    @JsonIgnore
    default String getAbbreviatedTitle() {
        return TextualObjects.get(getTitles(), TextualType.ABBREVIATION);
    }


     /**
     * Sets description if already set, otherwise {@link #addDescription(String, TextualType)}
     * @since 5.11
     */
    default void setDescription(String description, @NonNull TextualType type) {
        if (getDescriptions() != null) {
            for (D d : getDescriptions()) {
                if (d.getType() == type) {
                    d.set(description);
                    return;
                }
            }
        }
        addDescription(description, type);
    }

    /**
     * Updates a description with a {@link Supplier}, if at least the given supplier is not null.
     */
    default TO setDescription(@Nullable  Supplier up, @NonNull TextualType type) {
        if (up != null) {
            setDescription(up.get(), type);
        }
        return self();
    }

    /**
     * @since 5.5
     */
    @JsonIgnore
    BiFunction getDescriptionCreator();

    default TO addDescription(@Nullable String description, @NonNull TextualType type) {
        if (StringUtils.isNotEmpty(description)) {
            if (getDescriptions() == null) {
                setDescriptions(new TreeSet<>());
            }
            getDescriptions().add(getDescriptionCreator().apply(description, type));
        }
        return self();
    }


    SortedSet getDescriptions();

    void setDescriptions(SortedSet descriptions);


    /**
     * Default implementation based on {@link #getDescriptions()}, you may want to override this, if getDescriptions may modify
     * the object (it is e.g. required by hibernate that this will never return null
     */
    default boolean hasDescriptions() {
        return getDescriptions() != null && getDescriptions().size() > 0;
    }

    default TO addDescription(D description) {
        if (getDescriptions() == null) {
            setDescriptions(new TreeSet<>());
        }
        TextualObjects.addOrUpdate(getDescriptions(), description);
        return self();
    }

    default boolean removeDescription(D description) {
        return hasDescriptions() && getDescriptions().remove(description);
    }



    default boolean removeDescription(TextualType type) {
        boolean result = false;
        if (hasDescriptions()) {
            Iterator i = getDescriptions().iterator();
            while (i.hasNext()) {
                D d = i.next();
                if (d.getType() == type) {
                    i.remove();
                    result = true;
                }

            }
        }
        return result;
    }



    default D findDescription(@NonNull TextualType type) {
        if (hasDescriptions()) {
            for (D description : getDescriptions()) {
                if (type == description.getType()) {
                    return description;
                }
            }
        }
        return null;
    }


    /**
     * Returns the first available description. Probably the 'MAIN' description.
     */
    @JsonIgnore
    default String getMainDescription() {
        if (hasDescriptions()) {
            return getDescriptions().first().get();
        }
        return null;
    }

    default void setMainDescription(String description) {
        setDescription(description, TextualType.MAIN);
    }

    /**
     * Returns the description with textual type 'LONG' if there is one. Otherwise, returns {@link #getMainDescription()}
     */
    @JsonIgnore
    default String getLongDescription() {
        if (hasDescriptions()) {
            return TextualObjects.getOptional(getDescriptions(), TextualType.LONG).orElse(getMainDescription());
        } else {
            return null;
        }
    }

    default void setLongDescription(String description) {
        setDescription(description, TextualType.LONG);
    }

    @JsonIgnore
    default String getSubDescription() {
        if (hasDescriptions()) {
            for (D description : getDescriptions()) {
                if (TextualType.SUB == description.getType()) {
                    return description.get();
                }
            }
        }
        return null;
    }

    @JsonIgnore
    default String getShortDescription() {
        if (hasDescriptions()) {
            for (D description : getDescriptions()) {
                if (TextualType.SHORT == description.getType()) {
                    return description.get();
                }
            }
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy