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

org.nuiton.jaxx.widgets.config.model.ConfigUIModelBuilder Maven / Gradle / Ivy

package org.nuiton.jaxx.widgets.config.model;

/*
 * #%L
 * JAXX :: Widgets
 * %%
 * Copyright (C) 2008 - 2024 Code Lutin, 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 com.google.common.base.Preconditions;
import io.ultreia.java4all.config.ApplicationConfig;
import io.ultreia.java4all.config.spi.ConfigOptionDef;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.swing.Icon;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.io.File;

/**
 * A builder of {@link ConfigUIModel}
 * Created: 22 déc. 2009
 *
 * @author Tony Chemit - [email protected]
 * @since 2.5.11
 */
public class ConfigUIModelBuilder {

    private static final Logger log = LogManager.getLogger(ConfigUIModelBuilder.class);

    /** current model used */
    ConfigUIModel model;

    /** current category used */
    CategoryModel category;

    /** Current default callback used by a category. */
    String categoryDefaultCallBack;

    /** current option used */
    OptionModel option;

    /**
     * Create a new model and set it as current model.
     *
     * @param configurationBean configuration bean used in model (optional)
     * @param config            the configuration used in model (can not be null)
     * @param configFile        configuration file where to save (can not be null)
     * @return the builder
     * @throws IllegalStateException if there is already a current model
     * @throws NullPointerException  if config or configFile is {@code null}
     * @since 2.33
     */
    public ConfigUIModelBuilder createModel(Object configurationBean, ApplicationConfig config, File configFile) throws IllegalStateException, NullPointerException {
        checkNoCurrent(model, "model");
        // configuration bean can be null
        checkNotNull(config, "createModel", "config");
        checkNotNull(configFile, "createModel", "configFile");
        model = new ConfigUIModel(configurationBean, config, configFile);

        if (log.isDebugEnabled()) {
            log.debug("model created : " + model);
        }
        return this;
    }

    /**
     * Add a new category, and set it as current.
     *
     * Note: As side effets, if a previous category, then store it to
     * the model.
     *
     * @param categoryName  the name of the new category
     *                      (can not to be {@code null})
     * @param categoryLabel the label of the new category
     *                      (can not to be {@code null})
     * @return the builder
     * @throws IllegalStateException if there is not a current model,
     *                               nor category
     * @throws NullPointerException  if any of parameter is {@code null}
     */
    public ConfigUIModelBuilder addCategory(String categoryName, String categoryLabel)
            throws IllegalStateException, NullPointerException {
        checkCurrent(model, "model");
        checkNotNull(categoryName, "addCategory", "categoryName");
        checkNotNull(categoryLabel, "addCategory", "categoryLabel");
        flushCategory();
        category = new CategoryModel(categoryName, categoryLabel);
        if (log.isDebugEnabled()) {
            log.debug("category created : " + category);
        }
        return this;
    }

    /**
     * Add a new category, and set it as current.
     *
     * Note: As side effets, if a previous category, then store it to
     * the model.
     *
     * @param categoryName  the name of the new category (can not to be {@code null})
     * @param categoryLabel the label of the new category (can not to be {@code null})
     * @param defaultCallback default callback to sue
     * @return the builder
     * @throws IllegalStateException if there is not a current model,
     *                               nor category
     * @throws NullPointerException  if any of parameter is {@code null}
     */
    public ConfigUIModelBuilder addCategory(String categoryName, String categoryLabel, String defaultCallback)
            throws IllegalStateException, NullPointerException {
        checkCurrent(model, "model");
        checkNotNull(categoryName, "addCategory", "categoryName");
        checkNotNull(categoryLabel, "addCategory", "categoryLabel");
        flushCategory();
        categoryDefaultCallBack = defaultCallback;
        category = new CategoryModel(categoryName, categoryLabel);
        if (log.isDebugEnabled()) {
            log.debug("category created : " + category);
        }
        return this;
    }

    /**
     * Add a new option, and set it as current.
     *
     * Note: As side effects, if a previous option, then store it to
     * the model.
     *
     * @param def the def ot the new option
     * @return the builder
     * @throws IllegalStateException if there is not a current model,
     *                               nor category
     * @throws NullPointerException  if any of parameter is {@code null}
     */
    public ConfigUIModelBuilder addOption(ConfigOptionDef def)
            throws IllegalStateException, NullPointerException {
        checkCurrent(model, "model");
        checkCurrent(category, "category");
        checkNotNull(def, "addOption", "def");
        flushOption();
        Object value = model.getApplicationConfig().getOption(def);
        option = new OptionModel(def, value);
        if (categoryDefaultCallBack != null) {

            // use default callback
            model.registerOptionCallBack(categoryDefaultCallBack, option);
        }
        if (log.isDebugEnabled()) {
            log.debug("option created : " + option);
        }
        return this;
    }

    /**
     * Add a new option with a propertyName, and set it as current.
     *
     * Note: As side effets, if a previous option, then store it to
     * the model.
     *
     * Note: This method is a short-cut for
     * {@link #addOption(ConfigOptionDef)} then
     * {@link #setOptionPropertyName(String)}.
     *
     * @param def          the def ot the new option
     * @param propertyName the propertyName to set on the option
     * @return the builder
     * @throws IllegalStateException if there is not a current model, nor
     *                               category
     * @throws NullPointerException  if any of parameter is {@code null}
     * @deprecated since 2.5.29, prefer use the {@link #setOptionPropertyName(String)} method instead, will be removed soon
     */
    @Deprecated
    public ConfigUIModelBuilder addOption(ConfigOptionDef def,
                                          String propertyName)
            throws IllegalStateException, NullPointerException {
        addOption(def);
        checkNotNull(propertyName, "setOptionPropertyName", "propertyName");
        option.setPropertyName(propertyName);
        return this;
    }

    /**
     * Set the propertyName on the current option.
     *
     * @param propertyName the propertyName to set in the current option.
     * @return the builder
     * @throws IllegalStateException if there is not a current option set.
     * @throws NullPointerException  if any of parameter is {@code null}
     * @see OptionModel#setPropertyName(String)
     */
    public ConfigUIModelBuilder setOptionPropertyName(String propertyName)
            throws IllegalStateException, NullPointerException {
        checkCurrent(option, "option");
        checkNotNull(propertyName, "setOptionPropertyName", "propertyName");
        option.setPropertyName(propertyName);
        return this;
    }

    /**
     * Set the short label on the current option.
     *
     * @param shortLabel the propertyName to set in the current option.
     * @return the builder
     * @throws IllegalStateException if there is not a current option set.
     * @throws NullPointerException  if any of parameter is {@code null}
     * @see OptionModel#setShortLabel(String)
     * @since 2.5.29
     */
    public ConfigUIModelBuilder setOptionShortLabel(String shortLabel)
            throws IllegalStateException, NullPointerException {
        checkCurrent(option, "option");
        checkNotNull(shortLabel, "setShortLabel", "shortLabel");
        option.setShortLabel(shortLabel);
        return this;
    }

    /**
     * Set the editor on the current option.
     *
     * @param editor the editor to set in the current option.
     * @return the builder
     * @throws IllegalStateException if there is not a current option set.
     * @throws NullPointerException  if any of parameter is {@code null}
     * @see OptionModel#setEditor(TableCellEditor)
     */
    public ConfigUIModelBuilder setOptionEditor(TableCellEditor editor)
            throws IllegalStateException, NullPointerException {
        checkCurrent(option, "option");
        checkNotNull(editor, "setOptionEditor", "editor");
        option.setEditor(editor);
        return this;
    }

    /**
     * Set the renderer on the current option.
     *
     * @param renderer the renderer to set in the current option.
     * @return the builder
     * @throws IllegalStateException if there is not a current option set.
     * @throws NullPointerException  if any of parameter is {@code null}
     * @see OptionModel#setRenderer(TableCellRenderer)
     */
    public ConfigUIModelBuilder setOptionRenderer(TableCellRenderer renderer)
            throws IllegalStateException, NullPointerException {
        checkCurrent(option, "option");
        checkNotNull(renderer, "setOptionRenderer", "renderer");
        option.setRenderer(renderer);
        return this;
    }

    /**
     * Registers a new callback.
     *
     * Note: the order of registred callback is used to determine
     * the higher priority of callback to launch if required.
     *
     * @param name        the unique name of a callback
     * @param description the i18n key to describe the action
     * @param icon        the icon of the callBack (used in ui)
     * @param action      the action of the callback
     * @return the builder
     */
    public ConfigUIModelBuilder registerCallBack(String name,
                                                 String description,
                                                 Icon icon,
                                                 Runnable action) {
        checkCurrent(model, "model");
        checkNotNull(name, "registerCallBack", "name");
        checkNotNull(description, "registerCallBack", "description");
        checkNotNull(action, "registerCallBack", "action");
        model.registerCallBack(name, description, icon, action);
        return this;
    }

    /**
     * Registers the current option into a known callback.
     *
     * @param name the name of the callback
     * @return the builder
     */
    public ConfigUIModelBuilder setOptionCallBack(String name) {
        checkCurrent(option, "option");
        checkNotNull(name, "setOptionCallBack", "name");
        Preconditions.checkArgument(
                categoryDefaultCallBack == null,
                "You can not use the method *setOptionCallBack* when " +
                        "a default callback has been assigned to a category");

        model.registerOptionCallBack(name, option);
        return this;
    }

    /**
     * Sets the callback finalizet
     *
     * @param finalizer callback finalize
     * @return the builder
     * @see CallBackFinalizer
     */
    public ConfigUIModelBuilder setFinalizer(CallBackFinalizer finalizer) {
        model.setFinalizer(finalizer);
        return this;
    }

    /**
     * Sets the default callback to use for this category (the call back
     * will be add to all options of this category until you set another one or
     * nullify it).
     *
     * @param categoryDefaultCallBack default callbakc name for the category
     * @return the buider
     */
    public ConfigUIModelBuilder setCategoryDefaultCallBack(String categoryDefaultCallBack) {
        checkCurrent(model, "model");
        checkCurrent(category, "category");
        this.categoryDefaultCallBack = categoryDefaultCallBack;
        return this;
    }


    /**
     * Flush the model and return it.
     *
     * Note: As a side effect, nothing is available in the builder
     * after this operation.
     * To reuse the builder on a model, use the dedicated setter.
     *
     * @return the final model
     * @throws IllegalStateException if there is not a current model set.
     */
    public ConfigUIModel flushModel() throws IllegalStateException {
        checkCurrent(model, "model");
        flushCategory();
        ConfigUIModel result = model;
        model = null;
        return result;
    }

    /**
     * Set the given model as current model.
     *
     * Note: As side effets, il will clean current category and option.
     *
     * @param model the model to use
     * @return the buider
     * @throws IllegalStateException if there is already a current model
     */
    public ConfigUIModelBuilder setModel(ConfigUIModel model) throws IllegalStateException {
        checkNoCurrent(model, "model");
        this.model = model;
        if (log.isDebugEnabled()) {
            log.debug("new current model : " + this.model);
        }
        category = null;
        categoryDefaultCallBack = null;
        option = null;
        return this;
    }

    /**
     * Set the given category as current category.
     *
     * Note: As side effets, il will clean current option.
     *
     * @param categoryModel the category to use
     * @return the buider
     * @throws IllegalStateException if there is not a current model or a
     *                               current category
     */
    public ConfigUIModelBuilder setCategory(CategoryModel categoryModel)
            throws IllegalStateException {
        checkCurrent(model, "model");
        checkNoCurrent(category, "category");
        category = categoryModel;
        categoryDefaultCallBack = null;
        if (log.isDebugEnabled()) {
            log.debug("new current category : " + category);
        }
        option = null;
        return this;
    }

    /**
     * Sets the given option as current option.
     *
     * @param optionModel the option to use
     * @return the buider
     * @throws IllegalStateException if there is not a current model, nor
     *                               category, or a current option
     */
    public ConfigUIModelBuilder setOption(OptionModel optionModel)
            throws IllegalStateException {
        checkCurrent(model, "model");
        checkCurrent(category, "category");
        checkNoCurrent(option, "option");
        option = optionModel;
        if (log.isDebugEnabled()) {
            log.debug("new current option : " + option);
        }
        return this;
    }

    public ConfigUIModelBuilder setCloseAction(Runnable runnable) {
        checkNotNull(runnable, "setCloseAction", "runnable");
        checkCurrent(model, "model");
        model.setCloseAction(runnable);
        return this;
    }

    protected CategoryModel flushCategory() {
        CategoryModel result = category;
        if (category != null) {
            flushOption();
            // add the previous category to the model
            model.addCategory(category);
            category = null;
            categoryDefaultCallBack = null;
        }
        return result;
    }

    protected OptionModel flushOption() {
        OptionModel result = option;
        if (option != null) {
            // add the previous option to the category
            category.addOption(option);
            option = null;
        }
        return result;
    }

    protected void checkCurrent(Object o, String type) {
        if (o == null) {
            throw new IllegalStateException("no current " + type + "!");
        }
    }

    protected void checkNoCurrent(Object o, String type) {
        if (o != null) {
            throw new IllegalStateException(
                    "there is already a current " + type + "!");
        }
    }

    protected void checkNotNull(Object o, String method, String parameter) {
        if (o == null) {
            throw new NullPointerException(
                    "method " + method + " does not support null parameter " +
                            parameter + "!");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy