Class BTHistory
- All Implemented Interfaces:
Serializable,Tool
- Direct Known Subclasses:
BTAccountContactHistory,BTAccountHistory,BTAddressHistory,BTAddressHistory,BTAgendaHistory,BTAgendaHistory,BTAIConfigurationParamsHistory,BTAIModelHistory,BTAssetCharacteristicValueHistory,BTAssetContactHistory,BTAssetHistory,BTContactHistory,BTMaterialHistory,BTMaterialHistory,BTMeasureHistory,BTMeterConverterHistory,BTMeterHistory,BTMeterHistory,BTPermitObtainedHistory,BTPermitRequiredHistory,BTProjectActivityHistory,BTProjectDiaryHistory,BTProjectHeaderHistory,BTSerializedMaterialHistory,BTSkillConfigurationHistory,BTSkillDivisionHistory,BTStockHistory,BTTaskHistory,BTTechnicalObjectFeatureValueHistory,BTTechnicalObjectHeaderHistory,BTTimesheetHeaderHistory,BTWorkOrderHeaderHistory,BTWorkOrderOperationHistory
Abstract business task for managing entity history records.
This class provides a framework for tracking changes to entities by creating history records in dedicated history tables. It supports various operations including:
This class provides a framework for tracking changes to entities by creating history records in dedicated history tables. It supports various operations including:
- Creating history records alongside entity modifications (insert/update/delete)
- Creating history records for existing entities without modifying them
- Comparing current entity state with previous history records
- Translating entity fields to corresponding history table fields
- Since:
- 1.0
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected DBViewprotected DAOprotected DAOprotected intprotected static final Stringprotected static ConcurrentHashMap<String, HashGetter> protected HashGetterprotected booleanprotected static final LogChannelprotected Longprotected Longprotected Commandprotected intprotected static final intprotected static final int -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprotected voidapplyCommand(PoolKit pk) Applies the entity operation (insert, update, or delete).protected voidMain execution method of the history task.protected HashGetterBuilds the translation map from entity fields to history fields.protected voidCreates a history record for the current entity operation.protected HashGettercustomizeChangedFields(List<String> changedHistoryFields) Hook method for customizing history record values based on changed fields.protected voidcustomizeFieldMap(HashGetter hgMap) Hook method for customizing the field mapping between entity and history tables.protected abstract StringReturns a descriptive name for this history task.getChangedFields(HashGetter previousHistoryRecord, HashGetter newHistoryRecord) Identifies fields that have changed between two history records.Hook method for specifying additional fields to exclude from history record comparisons.intReturns the number of entity records affected by the operation.protected abstract StringReturns the prefix used in field names of the entity table.Returns a list of history table fields to exclude from change detection.protected String[]Returns an array of field names to exclude from history record comparisons.protected abstract StringReturns the name of the field in the history table that references the previous history record.protected abstract StringReturns the name of the field in the history table that stores the creation date.protected abstract StringReturns the name of the field in the entity table that references the history table.protected abstract StringReturns the name of the field in the history table that references the entity table.protected abstract StringReturns the name of the field in the history table that stores the operation code.Returns the ID of the newly created history record.protected StringReturns the name of the sequence field in the history table.protected StringgetHistoryTableField(String tableField, DBFields historyTableFieldMap) Maps an entity table field name to its corresponding history table field name.protected abstract StringReturns the prefix used in field names of the history table.protected StringReturns the name of the field in the history table that stores the user ID.protected LongConverts a command type to its corresponding numeric operation code.protected StringReturns the name of the field in the history table that stores stack trace information.protected StringGenerates a string representation of the current stack trace.Returns the list of valid operation modes supported by this history task.protected abstract voidInitializes the DAOs used by this history task.protected voidInserts a new record into the history table based on the current operation.protected booleanisDelete()Checks if the current operation is a DELETE operation.booleanIndicates whether a history record was successfully written.protected booleanisInsert()Checks if the current operation is an INSERT operation.protected booleanisUpdate()Checks if the current operation is an UPDATE operation.protected voidLoads the current database record for update or delete operations.protected HashGetterRetrieves the most recent history record for the given entity.protected voidLoads the field translation map between entity and history tables.protected voidHook method called after the entity operation is executed.protected voidHook method called before the entity operation is executed.voidsetCommandAndHistoryParams(Command operationMode, Map<String, Object> filters, Map<String, Object> values) Configures the task to perform both an entity operation and history recording.voidsetHistoryParams(Command.Type type, Map<String, Object> filters) Configures the task to perform only history recording without modifying the entity.protected booleanDetermines whether to record the current stack trace in the history record.protected HashGettertranslateFields(Map<String, Object> hgValues) Translates entity field values to their corresponding history field values.protected voidValidates input parameters before starting the history operation.protected voidwriteHistoryRecord(Map<String, Object> currentValues, HashGetter previousHistoryRecord, PoolKit pk) Writes a new history record to the history table.Methods inherited from class overit.geocall.bl.BusinessTask
start, start, startAlone, startInBackground
-
Field Details
-
LOG
-
HISTORY_TABLE_TRANSLATE_FIELD_CACHE
-
dao
-
daoHistory
-
validModes
-
operationMode
-
operationCode
-
TYPE_COMMAND_AND_HISTORY
protected static final int TYPE_COMMAND_AND_HISTORY- See Also:
-
TYPE_ONLY_HISTORY
protected static final int TYPE_ONLY_HISTORY- See Also:
-
operationType
protected int operationType -
filters
-
values
-
historyFieldsMap
-
currentDBValues
-
elaboratedRows
protected int elaboratedRows -
historyWritten
protected boolean historyWritten -
newHistoryRecordId
-
HISTORY_CACHE_NAME
- See Also:
-
-
Constructor Details
-
BTHistory
public BTHistory()
-
-
Method Details
-
getValidOperationModes
Returns the list of valid operation modes supported by this history task. By default, this includes INSERT, UPDATE (by PK and by filter), and DELETE (by PK and by filter) operations. Subclasses can override this method to provide a different set of valid operations.- Returns:
- a list of valid Command objects
-
setCommandAndHistoryParams
public void setCommandAndHistoryParams(Command operationMode, Map<String, Object> filters, Map<String, Object> values) Configures the task to perform both an entity operation and history recording. This method sets up the task to execute a database command on the entity table and then record the change in the history table.- Parameters:
operationMode- the DAO command to execute (INSERT, UPDATE, DELETE)filters- the criteria to identify records for update or delete operationsvalues- the new values to apply in insert or update operations
-
setHistoryParams
Configures the task to perform only history recording without modifying the entity. This method sets up the task to create a history record for an existing entity without performing any modifications to the entity itself.- Parameters:
type- the type of operation to record in history (INSERT, UPDATE, DELETE)filters- the criteria to identify the entity record for history recording
-
getHistoryRecordId
Returns the ID of the newly created history record.- Returns:
- the ID of the history record, or null if no record was created
-
getElaboratedRows
public int getElaboratedRows()Returns the number of entity records affected by the operation.- Returns:
- the count of affected records
-
isHistoryWritten
public boolean isHistoryWritten()Indicates whether a history record was successfully written.- Returns:
- true if a history record was written, false otherwise
-
body
Main execution method of the history task. This method orchestrates the entire history recording process:- Initializes the DAOs
- Validates input parameters
- Loads current database data if needed
- Applies the entity operation if in COMMAND_AND_HISTORY mode
- Creates the history record
- Specified by:
bodyin classBusinessTask<Void>- Parameters:
v- void parameter (not used)pk- thePoolKit- Throws:
DAException- if a data access error occursDAValidateException- if validation fails
-
getBTDescription
Returns a descriptive name for this history task. This name is used for logging purposes to identify the specific history task being executed.- Returns:
- a string describing the task
-
initializeDAO
protected abstract void initializeDAO()Initializes the DAOs used by this history task. Implementations must set:- dao: for entity table operations (insert/update/delete)
- daoHistory: for history table operations
-
validateParams
Validates input parameters before starting the history operation. This method checks that all required parameters are properly set based on the operation type. It verifies:- DAOs are initialized
- Operation type is valid
- Operation mode is valid (for COMMAND_AND_HISTORY)
- Filters are provided when required
- Values are provided when required
- Throws:
DAValidateException- if any validation check fails
-
loadCurrentDBData
Loads the current database record for update or delete operations. This method retrieves the current state of the entity record before applying modifications, so it can be compared with the new state when creating the history record.- Parameters:
pk- thePoolKit- Throws:
DAException- if a data access error occursDAValidateException- if validation fails
-
applyCommand
Applies the entity operation (insert, update, or delete). This method executes the specified command on the entity table using the provided filters and values. It calls preElaboration before and postElaboration after the command execution to allow for customizations.- Parameters:
pk- thePoolKit- Throws:
DAException- if a data access error occursDAValidateException- if validation fails
-
postElaboration
Hook method called after the entity operation is executed. This method is called after the entity has been modified (inserted, updated, or deleted). Subclasses can override this method to perform additional actions after the entity operation completes successfully.- Parameters:
pk- thePoolKit- Throws:
DAException- if a data access error occursDAValidateException- if validation fails
-
preElaboration
Hook method called before the entity operation is executed. This method is called before the entity is modified (inserted, updated, or deleted). Subclasses can override this method to perform additional actions before the entity operation begins.- Parameters:
pk- thePoolKit- Throws:
DAException- if a data access error occursDAValidateException- if validation fails
-
createHistoryRecord
Creates a history record for the current entity operation. This method orchestrates the history record creation process by:- Loading the field translation map between entity and history tables
- Inserting the appropriate history record based on the operation type
- Parameters:
pk- thePoolKit- Throws:
DAException- if a data access error occursDAValidateException- if validation fails
-
loadTranslatedFieldMap
Loads the field translation map between entity and history tables. This method retrieves or builds a mapping between entity table fields and their corresponding history table fields. The mapping is cached in a static ConcurrentHashMap to improve performance for subsequent operations. The cache key is constructed from the pool name and table name to ensure uniqueness across different entity types.- Parameters:
pk- thePoolKit- Throws:
DAValidateException- if validation fails during map buildingDAException- if a data access error occurs during map building
-
buildMap
Builds the translation map from entity fields to history fields. This method analyzes the database schema for both the entity table and history table, and creates a mapping between corresponding fields. It follows naming conventions to determine field correspondences, handling different prefixes for standard and custom fields. Special fields like LOGIN, ACTION, and DATASTAMP are excluded from the mapping. The method also provides a hook point for customizations through the customizeFieldMap method.- Parameters:
pk- thePoolKit- Returns:
- a
HashGettercontaining the translation map from entity field names to history field names - Throws:
DAValidateException- if validation fails during schema retrievalDAException- if a data access error occurs during schema retrieval
-
getHistorySequenceField
Returns the name of the sequence field in the history table.- Returns:
- the name of the sequence field in the history table
-
getHistoryTableField
Maps an entity table field name to its corresponding history table field name. This method applies naming conventions to determine the corresponding field name in the history table for a given entity table field. It handles several patterns:- Standard geocall/crm fields: replaces entity prefix with history prefix
- Geocall/crm fields mapped to WFM fields: replaces entity prefix with "XWFM" + history prefix
- WFM/custom fields: handles "X..." prefixed fields with appropriate transformations
- Parameters:
tableField- the entity field name to maphistoryTableFieldMap- theDBFieldscontaining all fields in the history table- Returns:
- the corresponding history field name, or null if no matching field exists
-
customizeFieldMap
Hook method for customizing the field mapping between entity and history tables. This method provides a customization point for subclasses to modify the automatically generated field mapping. Subclasses can override this method to:- Add mappings for fields that don't follow standard naming conventions
- Remove mappings that should not be included in history records
- Modify existing mappings to handle special cases
- Parameters:
hgMap- the translation map from entity fields to history fields to be customized
-
getEntityTablePrefix
Returns the prefix used in field names of the entity table.- Returns:
- the prefix string used in field names of the entity table
-
getHistoryTablePrefix
Returns the prefix used in field names of the history table.- Returns:
- the prefix string used in field names of the history table
-
insertHistoryRecord
Inserts a new record into the history table based on the current operation. This method handles different scenarios based on the operation type:- For TYPE_COMMAND_AND_HISTORY with INSERT: Creates a history record from the new values
- For TYPE_COMMAND_AND_HISTORY with UPDATE/DELETE: Creates history records for affected rows
- For TYPE_ONLY_HISTORY: Loads the current entity record and creates a history record if needed
- Parameters:
pk- thePoolKit- Throws:
DAValidateException- if validation fails during record insertionDAException- if a data access error occurs during record insertion
-
loadPreviousHistoryRecord
protected HashGetter loadPreviousHistoryRecord(HashGetter hg, PoolKit pk) throws DAException, DAValidateException Retrieves the most recent history record for the given entity. This method looks up the previous history record for an entity by using the foreign key stored in the entity record. This allows for tracking the chain of changes made to an entity over time. If no previous history record exists for the entity, or if the foreign key is null, this method returns null.- Parameters:
hg- the entity record data as aHashGetterpk- thePoolKit- Returns:
- the previous history record as a
HashGetter, or null if no previous record exists - Throws:
DAValidateException- if validation fails during record retrievalDAException- if a data access error occurs during record retrieval
-
getHistoryField
Returns the name of the field in the entity table that references the history table.- Returns:
- the name of the field in the entity table that references the history table
-
getFieldsToExclude
Returns an array of field names to exclude from history record comparisons. When comparing a current entity state with its previous history record to determine if changes have occurred, certain fields should be excluded from the comparison. This method builds a list of such fields, including:- Primary key of the history table
- Foreign key to the previous history record
- Date field recording when the history record was created
- Operation field indicating the type of operation (INSERT/UPDATE/DELETE)
- Standard audit fields (INSERTED, UPDATED, DELETED)
- Custom fields specified by subclasses via getCustomFieldsToExclude()
- Returns:
- an array of field names to exclude from history record comparisons
-
getHistoryDateField
Returns the name of the field in the history table that stores the creation date.- Returns:
- the name of the date field in the history table
-
getForeignHistoryField
Returns the name of the field in the history table that references the previous history record.- Returns:
- the name of the field in the history table that references the previous history record
-
getHistoryUserField
Returns the name of the field in the history table that stores the user ID.- Returns:
- the name of the user ID field in the history table, or null if user tracking is not enabled
-
getCustomFieldsToExclude
Hook method for specifying additional fields to exclude from history record comparisons.- Returns:
- a list of additional field names to exclude from history record comparisons
-
translateFields
Translates entity field values to their corresponding history field values. This method applies the field mapping to convert entity data into the format required for the history table. It:- Maps entity field names to history field names using the translation map
- Adds the foreign key reference to the entity record
- Sets the operation code (INSERT/UPDATE/DELETE)
- Sets the timestamp for the history record
- Sets the user ID if user tracking is enabled
- Parameters:
hgValues- the entity data to translate- Returns:
- a new
HashGettercontaining the translated values for the history record
-
getOperationCodeValue
Converts a command type to its corresponding numeric operation code. This method maps the standard database operation types to numeric codes that can be stored in the history table:- INSERT: 1
- UPDATE: 2
- DELETE: 3
- Parameters:
type- the command type to convert- Returns:
- the numeric operation code, or null if the type is not recognized
-
getHistoryForeignField
Returns the name of the field in the history table that references the entity table.- Returns:
- the name of the field in the history table that references the entity table
-
getHistoryOperationField
Returns the name of the field in the history table that stores the operation code.- Returns:
- the name of the operation code field in the history table
-
writeHistoryRecord
protected void writeHistoryRecord(Map<String, Object> currentValues, HashGetter previousHistoryRecord, PoolKit pk) throws DAValidateException, DAExceptionWrites a new history record to the history table. This method performs the actual insertion of a history record based on the current entity values and, optionally, the previous history record. It:- Translates entity field values to history field values
- Identifies changed fields if a previous history record exists
- Adds stack trace information if enabled
- Inserts the new history record
- Updates the entity record to reference the new history record
- Parameters:
currentValues- the current entity valuespreviousHistoryRecord- the previous history record, or null if none existspk- thePoolKit- Throws:
DAValidateException- if validation fails during record insertionDAException- if a data access error occurs during record insertion
-
getChangedFields
protected List<String> getChangedFields(HashGetter previousHistoryRecord, HashGetter newHistoryRecord) Identifies fields that have changed between two history records. This method compares the previous history record with the new history record to determine which fields have changed.- Parameters:
previousHistoryRecord- the previous history recordnewHistoryRecord- the new history record- Returns:
- a list of field names that have changed between the two records
-
getExcludedHistoryFieldsFromComparison
Returns a list of history table fields to exclude from change detection. This method builds a list of fields that should be ignored when comparing history records to determine if changes have occurred. These include:- Standard audit fields (DELETED, INSERTED, UPDATED)
- Primary key fields of the history table
- Foreign key to the previous history record
- Operation code field
- Date field
- Returns:
- a list of field names to exclude from history record comparisons
-
customizeChangedFields
Hook method for customizing history record values based on changed fields. This method is called before inserting a new history record when a previous history record exists.- Parameters:
changedHistoryFields- the list of field names that have changed- Returns:
- a HashGetter containing custom values to add to the history record
-
getStackTraceField
Returns the name of the field in the history table that stores stack trace information. By default, this method returns null, indicating that stack trace recording is not enabled. Subclasses can override this method to enable stack trace recording.- Returns:
- the name of the stack trace field in the history table, or null if stack trace recording is not enabled
-
traceCurrentStack
protected boolean traceCurrentStack()Determines whether to record the current stack trace in the history record. By default, this method returns false, indicating that stack trace recording is not enabled. Subclasses can override this method to enable stack trace recording based on specific conditions.- Returns:
- true if the current stack trace should be recorded, false otherwise
-
getStackTraceString
Generates a string representation of the current stack trace. The resulting string is truncated to a maximum of 4000 characters to ensure it fits within database field size limits.- Returns:
- a string representation of the filtered stack trace
-
isDelete
protected boolean isDelete()Checks if the current operation is a DELETE operation.- Returns:
- true if the current operation is a DELETE, false otherwise
-
isInsert
protected boolean isInsert()Checks if the current operation is an INSERT operation.- Returns:
- true if the current operation is an INSERT, false otherwise
-
isUpdate
protected boolean isUpdate()Checks if the current operation is an UPDATE operation.- Returns:
- true if the current operation is an UPDATE, false otherwise
-