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

is.codion.swing.framework.model.SwingEntityModelBuilder Maven / Gradle / Ivy

There is a newer version: 0.18.25
Show newest version
/*
 * This file is part of Codion.
 *
 * Codion is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Codion 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 Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Codion.  If not, see .
 *
 * Copyright (c) 2011 - 2024, Björn Darri Sigurðsson.
 */
package is.codion.swing.framework.model;

import is.codion.framework.db.EntityConnectionProvider;
import is.codion.framework.domain.entity.EntityType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;

import static java.util.Objects.requireNonNull;

/**
 * A default {@link SwingEntityModel.Builder} implementation.
 */
final class SwingEntityModelBuilder implements SwingEntityModel.Builder {

  private static final Logger LOG = LoggerFactory.getLogger(SwingEntityModelBuilder.class);

  private static final String CONNECTION_PROVIDER_PARAMETER = "connectionProvider";

  private final EntityType entityType;
  private final List detailModelBuilders = new ArrayList<>();

  private Class modelClass;
  private Class editModelClass;
  private Class tableModelClass;

  private Function modelFactory;
  private Function editModelFactory;
  private Function tableModelFactory;

  private Consumer onBuildModel = new EmptyOnBuild<>();
  private Consumer onBuildEditModel = new EmptyOnBuild<>();
  private Consumer onBuildTableModel = new EmptyOnBuild<>();

  /**
   * Instantiates a new SwingeEntityModel.Builder based on the given entityType
   * @param entityType the entityType
   */
  SwingEntityModelBuilder(EntityType entityType) {
    this.entityType = requireNonNull(entityType, "entityType");
  }

  @Override
  public EntityType entityType() {
    return entityType;
  }

  @Override
  public SwingEntityModel.Builder modelClass(Class modelClass) {
    if (editModelClass != null || tableModelClass != null) {
      throw new IllegalStateException("Edit or table model class has been set");
    }
    this.modelClass = requireNonNull(modelClass, "modelClass");
    return this;
  }

  @Override
  public SwingEntityModel.Builder editModelClass(Class editModelClass) {
    if (modelClass != null) {
      throw new IllegalStateException("Model class has been set");
    }
    if (tableModelClass != null) {
      throw new IllegalStateException("TableModel class has been set");
    }
    this.editModelClass = requireNonNull(editModelClass, "editModelClass");
    return this;
  }

  @Override
  public SwingEntityModel.Builder tableModelClass(Class tableModelClass) {
    if (modelClass != null) {
      throw new IllegalStateException("Model class has been set");
    }
    if (editModelClass != null) {
      throw new IllegalStateException("EditModel class has been set");
    }
    this.tableModelClass = requireNonNull(tableModelClass, "tableModelClass");
    return this;
  }

  @Override
  public SwingEntityModel.Builder modelFactory(Function modelFactory) {
    this.modelFactory = requireNonNull(modelFactory);
    return this;
  }

  @Override
  public SwingEntityModel.Builder editModelFactory(Function editModelFactory) {
    this.editModelFactory = requireNonNull(editModelFactory);
    return this;
  }

  @Override
  public SwingEntityModel.Builder tableModelFactory(Function tableModelFactory) {
    this.tableModelFactory = requireNonNull(tableModelFactory);
    return this;
  }

  @Override
  public SwingEntityModel.Builder onBuildModel(Consumer onBuildModel) {
    this.onBuildModel = requireNonNull(onBuildModel);
    return this;
  }

  @Override
  public SwingEntityModel.Builder onBuildEditModel(Consumer onBuildEditModel) {
    this.onBuildEditModel = requireNonNull(onBuildEditModel);
    return this;
  }

  @Override
  public SwingEntityModel.Builder onBuildTableModel(Consumer onBuildTableModel) {
    this.onBuildTableModel = requireNonNull(onBuildTableModel);
    return this;
  }

  @Override
  public SwingEntityModel.Builder detailModelBuilder(SwingEntityModel.Builder detailModelBuilder) {
    requireNonNull(detailModelBuilder, "detailModelBuilder");
    if (!detailModelBuilders.contains(detailModelBuilder)) {
      detailModelBuilders.add(detailModelBuilder);
    }

    return this;
  }

  @Override
  public SwingEntityModel buildModel(EntityConnectionProvider connectionProvider) {
    requireNonNull(connectionProvider, CONNECTION_PROVIDER_PARAMETER);
    try {
      SwingEntityModel model;
      if (modelFactory != null) {
        LOG.debug("{} modelBuilder initializing entity model", this);
        model = modelFactory.apply(connectionProvider);
      }
      else if (modelClass().equals(SwingEntityModel.class)) {
        LOG.debug("{} initializing a default entity model", this);
        model = buildDefaultModel(connectionProvider);
      }
      else {
        LOG.debug("{} initializing a custom entity model: {}", this, modelClass());
        model = modelClass().getConstructor(EntityConnectionProvider.class).newInstance(connectionProvider);
      }
      for (SwingEntityModel.Builder detailProvider : detailModelBuilders) {
        model.addDetailModel(detailProvider.buildModel(connectionProvider));
      }
      onBuildModel.accept(model);

      return model;
    }
    catch (RuntimeException re) {
      throw re;
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public SwingEntityEditModel buildEditModel(EntityConnectionProvider connectionProvider) {
    requireNonNull(connectionProvider, CONNECTION_PROVIDER_PARAMETER);
    try {
      SwingEntityEditModel editModel;
      if (editModelFactory != null) {
        LOG.debug("{} editModelBuilder initializing edit model", this);
        editModel = editModelFactory.apply(connectionProvider);
      }
      else if (editModelClass().equals(SwingEntityEditModel.class)) {
        LOG.debug("{} initializing a default edit model", this);
        editModel = new SwingEntityEditModel(entityType, connectionProvider);
      }
      else {
        LOG.debug("{} initializing a custom edit model: {}", this, editModelClass());
        editModel = editModelClass().getConstructor(EntityConnectionProvider.class).newInstance(connectionProvider);
      }
      onBuildEditModel.accept(editModel);

      return editModel;
    }
    catch (RuntimeException re) {
      throw re;
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public SwingEntityTableModel buildTableModel(EntityConnectionProvider connectionProvider) {
    requireNonNull(connectionProvider, CONNECTION_PROVIDER_PARAMETER);
    try {
      SwingEntityTableModel tableModel;
      if (tableModelFactory != null) {
        LOG.debug("{} tableModelBuilder initializing table model", this);
        tableModel = tableModelFactory.apply(connectionProvider);
      }
      else if (tableModelClass().equals(SwingEntityTableModel.class)) {
        LOG.debug("{} initializing a default table model", this);
        tableModel = new SwingEntityTableModel(buildEditModel(connectionProvider));
      }
      else {
        LOG.debug("{} initializing a custom table model: {}", this, tableModelClass());
        tableModel = tableModelClass().getConstructor(EntityConnectionProvider.class).newInstance(connectionProvider);
      }
      onBuildTableModel.accept(tableModel);

      return tableModel;
    }
    catch (RuntimeException re) {
      throw re;
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public boolean equals(Object obj) {
    if (obj instanceof SwingEntityModelBuilder) {
      SwingEntityModelBuilder that = (SwingEntityModelBuilder) obj;

      return Objects.equals(entityType, that.entityType) &&
              Objects.equals(modelClass, that.modelClass) &&
              Objects.equals(editModelClass, that.editModelClass) &&
              Objects.equals(tableModelClass, that.tableModelClass);
    }

    return false;
  }

  @Override
  public int hashCode() {
    return Objects.hash(entityType, modelClass, editModelClass, tableModelClass);
  }

  private SwingEntityModel buildDefaultModel(EntityConnectionProvider connectionProvider) {
    return new SwingEntityModel(buildTableModel(connectionProvider));
  }

  private Class modelClass() {
    return modelClass == null ? SwingEntityModel.class : modelClass;
  }

  private Class editModelClass() {
    return editModelClass == null ? SwingEntityEditModel.class : editModelClass;
  }

  private Class tableModelClass() {
    return tableModelClass == null ? SwingEntityTableModel.class : tableModelClass;
  }

  private static final class EmptyOnBuild implements Consumer {
    @Override
    public void accept(T panel) {/*Do nothing*/}
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy