is.codion.framework.model.EntityEditModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of codion-framework-model Show documentation
Show all versions of codion-framework-model Show documentation
Codion Application Framework
/*
* 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) 2009 - 2024, Björn Darri Sigurðsson.
*/
package is.codion.framework.model;
import is.codion.common.Configuration;
import is.codion.common.db.exception.DatabaseException;
import is.codion.common.observer.Mutable;
import is.codion.common.observer.Observer;
import is.codion.common.property.PropertyValue;
import is.codion.common.state.State;
import is.codion.common.state.StateObserver;
import is.codion.common.value.Value;
import is.codion.framework.db.EntityConnection;
import is.codion.framework.db.EntityConnectionProvider;
import is.codion.framework.domain.entity.Entities;
import is.codion.framework.domain.entity.Entity;
import is.codion.framework.domain.entity.EntityDefinition;
import is.codion.framework.domain.entity.EntityType;
import is.codion.framework.domain.entity.EntityValidator;
import is.codion.framework.domain.entity.attribute.Attribute;
import is.codion.framework.domain.entity.attribute.AttributeDefinition;
import is.codion.framework.domain.entity.attribute.ForeignKey;
import is.codion.framework.domain.entity.exception.ValidationException;
import java.util.Collection;
import java.util.Map;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Specifies a class for editing {@link Entity} instances.
* The underlying attribute values are available via {@link #value(Attribute)}.
*/
public interface EntityEditModel {
/**
* Specifies whether foreign key values should persist by default when defaults are set
*
* - Value type: Boolean
*
- Default value: true
*
* @see EditableEntity#defaults()
*/
PropertyValue PERSIST_FOREIGN_KEYS = Configuration.booleanValue(EntityEditModel.class.getName() + ".persistForeignKeys", true);
/**
* Specifies whether edit models post their insert, update and delete events to {@link EntityEditEvents}
*
* - Value type: Boolean
*
- Default value: true
*
* @see #postEditEvents()
* @see EntityTableModel#HANDLE_EDIT_EVENTS
*/
PropertyValue POST_EDIT_EVENTS = Configuration.booleanValue(EntityEditModel.class.getName() + ".postEditEvents", true);
/**
* @return the type of the entity this edit model is based on
*/
EntityType entityType();
/**
* @return the connection provider used by this edit model
*/
EntityConnectionProvider connectionProvider();
/**
* Do not cache or keep the connection returned by this method in a long living field,
* since it may become invalid and thereby unusable.
* @return the connection used by this edit model
*/
EntityConnection connection();
/**
* Returns a {@link EditableEntity} wrapping the entity being edited. {@link EditableEntity#get()} returns
* an immutable copy of the {@link Entity} instance being edited, while {@link EditableEntity#set(Object)}
* copies the values from the given {@link Entity} into the underlying {@link Entity}.
* Note that value changes must go through the {@link EditableValue} accessible via {@link #value(Attribute)}.
* @return the {@link EditableEntity} wrapping the {@link Entity} instance being edited
* @see Entity#immutable()
*/
EditableEntity entity();
/**
* Returns the {@link EditableValue} instance representing {@code attribute} in this edit model.
* @param attribute the attribute
* @param the value type
* @return the {@link EditableValue} representing the given attribute
*/
EditableValue value(Attribute attribute);
/**
* @return the underlying domain entities
*/
Entities entities();
/**
* @return the definition of the underlying entity
*/
EntityDefinition entityDefinition();
/**
* Making this edit model read-only prevents any changes from being
* persisted to the database, trying to insert, update or delete will
* cause an exception being thrown, it does not prevent editing.
* Use {@link #insertEnabled()}, {@link #updateEnabled()} and {@link #deleteEnabled()}
* to configure the enabled state of those specific actions.
* @return the {@link State} controlling whether this model is read only
*/
State readOnly();
/**
* Disabling insert causes an exception being thrown when inserting.
* @return the {@link State} controlling whether inserting is enabled via this edit model
*/
State insertEnabled();
/**
* Disabling update causes an exception being thrown when updating.
* @return the {@link State} controlling whether updating is enabled via this edit model
*/
State updateEnabled();
/**
* Disabling updating multiple entities causes an exception being thrown when
* trying to update multiple entities at a time.
* @return the {@link State} controlling whether updating multiple entities is enabled
*/
State updateMultipleEnabled();
/**
* Disabling delete causes an exception being thrown when deleting.
* @return the {@link State} controlling whether deleting is enabled via this edit model
*/
State deleteEnabled();
/**
* Creates a {@link EntitySearchModel} for looking up entities referenced by the given foreign key,
* using the search attributes defined for that entity type.
* @param foreignKey the foreign key for which to create a {@link EntitySearchModel}
* @return a {@link EntitySearchModel} for looking up entities of the type referenced by the given foreign key attribute,
* @throws IllegalStateException in case no searchable attributes can be found for the entity type referenced by the given foreign key
*/
EntitySearchModel createForeignKeySearchModel(ForeignKey foreignKey);
/**
* @param foreignKey the foreign key for which to retrieve the {@link EntitySearchModel}
* @return the {@link EntitySearchModel} associated with the {@code foreignKey}, if no search model
* has been initialized for the given foreign key, a new one is created, associated with the foreign key and returned.
*/
EntitySearchModel foreignKeySearchModel(ForeignKey foreignKey);
/**
* @return a state controlling whether this edit model posts insert, update and delete events
* on the {@link EntityEditEvents} event bus.
* @see #POST_EDIT_EVENTS
*/
State postEditEvents();
/**
* Note: This method must be called on the UI thread in case a panel has been based on this model.
* Performs an insert on the active entity, sets the primary key values of the active entity
* according to the primary key of the inserted entity
* @return the inserted entity
* @throws DatabaseException in case of a database exception
* @throws ValidationException in case validation fails
* @throws IllegalStateException in case inserting is not enabled
* @see EntityValidator#validate(Entity)
*/
Entity insert() throws DatabaseException, ValidationException;
/**
* Note: This method must be called on the UI thread in case a panel has been based on this model.
* Performs an insert on the given entities.
* @param entities the entities to insert
* @return a list containing the inserted entities
* @throws DatabaseException in case of a database exception
* @throws ValidationException in case validation fails
* @throws IllegalStateException in case inserting is not enabled
* @see #beforeInsert()
* @see #afterInsert()
* @see EntityValidator#validate(Entity)
*/
Collection insert(Collection entities) throws DatabaseException, ValidationException;
/**
* Note: This method must be called on the UI thread in case a panel has been based on this model.
* Performs an update on the active entity
* @return the updated entity
* @throws DatabaseException in case of a database exception
* @throws is.codion.common.db.exception.RecordModifiedException in case the entity has been modified since it was loaded
* @throws ValidationException in case validation fails
* @throws IllegalStateException in case updating is not enabled
* @throws is.codion.common.db.exception.UpdateException in case the active entity is not modified
* @see EntityValidator#validate(Entity)
*/
Entity update() throws DatabaseException, ValidationException;
/**
* Note: This method must be called on the UI thread in case a panel has been based on this model.
* Updates the given entities.
* @param entities the entities to update
* @return the updated entities
* @throws DatabaseException in case of a database exception
* @throws is.codion.common.db.exception.RecordModifiedException in case an entity has been modified since it was loaded
* @throws ValidationException in case validation fails
* @throws IllegalStateException in case updating is not enabled
* @see #beforeUpdate()
* @see #afterUpdate()
* @see EntityValidator#validate(Entity)
*/
Collection update(Collection entities) throws DatabaseException, ValidationException;
/**
* Note: This method must be called on the UI thread in case a panel has been based on this model.
* @return the deleted entity
* @throws DatabaseException in case of a database exception
* @throws IllegalStateException in case deleting is not enabled
* @see #beforeDelete()
* @see #afterDelete()
*/
Entity delete() throws DatabaseException;
/**
* Note: This method must be called on the UI thread in case a panel has been based on this model.
* @param entities the entities to delete
* @return the deleted entities
* @throws DatabaseException in case of a database exception
* @throws IllegalStateException in case deleting is not enabled
* @see #beforeDelete()
* @see #afterDelete()
*/
Collection delete(Collection entities) throws DatabaseException;
/**
* Creates a new {@link Insert} instance for inserting the active entity.
* @return a new {@link Insert} instance
* @throws ValidationException in case validation fails
*/
Insert createInsert() throws ValidationException;
/**
* Creates a new {@link Insert} instance for inserting the given entities.
* @param entities the entities to insert
* @return a new {@link Insert} instance
* @throws ValidationException in case validation fails
*/
Insert createInsert(Collection entities) throws ValidationException;
/**
* Creates a new {@link Update} instance for updating the active entity.
* @return a new {@link Update} instance
* @throws IllegalArgumentException in case the active entity is unmodified
* @throws ValidationException in case validation fails
*/
Update createUpdate() throws ValidationException;
/**
* Creates a new {@link Update} instance for updating the given entities.
* @param entities the entities to update
* @return a new {@link Update} instance
* @throws IllegalArgumentException in case any of the given entities are unmodified
* @throws ValidationException in case validation fails
*/
Update createUpdate(Collection entities) throws ValidationException;
/**
* Creates a new {@link Delete} instance for deleting the active entity.
* @return a new {@link Delete} instance
*/
Delete createDelete();
/**
* Creates a new {@link Delete} instance for deleting the given entities.
* @param entities the entities to delete
* @return a new {@link Delete} instance
*/
Delete createDelete(Collection entities);
/**
* Adds the given entities to all foreign key models based on that entity type
* @param foreignKey the foreign key
* @param entities the values
*/
void add(ForeignKey foreignKey, Collection entities);
/**
* Removes the given entities from all foreign key models based on that entity type and clears any foreign
* key values referencing them.
* @param foreignKey the foreign key
* @param entities the values
*/
void remove(ForeignKey foreignKey, Collection entities);
/**
* For every field referencing the given foreign key values, replaces that foreign key instance with
* the corresponding entity from {@code entities}, useful when attribute
* values have been changed in the referenced entity that must be reflected in the edit model.
* @param foreignKey the foreign key
* @param entities the foreign key entities
*/
void replace(ForeignKey foreignKey, Collection entities);
/**
* Validates the value associated with the given attribute, using the underlying validator.
* @param attribute the attribute the value is associated with
* @throws ValidationException if the given value is not valid for the given attribute
*/
void validate(Attribute> attribute) throws ValidationException;
/**
* Validates the given entities, using the underlying validator.
* For entities of a type other than this edit model is based on,
* their respective validators are used.
* @param entities the entities to validate
* @throws ValidationException on finding the first invalid entity
* @see EntityDefinition#validator()
*/
void validate(Collection entities) throws ValidationException;
/**
* Validates the given entity, using the underlying validator.
* For entities of a type other than this edit model is based on,
* their respective validators are used.
* @param entity the entity to validate
* @throws ValidationException in case the entity is invalid
* @throws NullPointerException in case the entity is null
*/
void validate(Entity entity) throws ValidationException;
/**
* @return an observer notified before an insert is performed
*/
Observer> beforeInsert();
/**
* @return an observer notified after an insert is performed
*/
Observer> afterInsert();
/**
* @return an observer notified before an update is performed
*/
Observer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy