Attribute history supposes that every user object (SWRecord
) can have several attributes. Attribute is
an entity that has a name and a value. We're working with textual attributes, i.e. values are of the
String
type. It doesn't matter what are the attributes and where they are stored, we consider only their
changes here.
Every attrubute change is a part of a user action. User action is described by the {@link com.supportwizard.functionalities.attributehistory.ejb.SWAttributeHistoryLogRecordBean SWAttributeHistoryLogRecord} bean and holds the following data:
SWAttributeHistoryLogRecord
and SWAttributeChange
is showed in the
following entity diagram:
This package has 4 main tasks:
SWTable table = ... SWAttributeHistoryFunctionalityHome attributeHistoryFunctionalityHome; SWAttributeHistoryFunctionality attributeHistoryFunctionality; attributeHistoryFunctionalityHome = (SWAttributeHistoryFunctionalityHome) PortableRemoteObject.narrow( new InitialContext().lookup("functionalities/attributehistoru/SWAttributeHistoryFunctionality"), SWAttributeHistoryFunctionalityHome.class); attributeHistoryFunctionality = attributeHistoryFunctionalityHome.create(table);Now attribute history can be added using {@link com.supportwizard.functionalities.attributehistory.ejb.SWAttributeHistoryWriterBean#addHistoryData(com.supportwizard.seance.Seance, com.supportwizard.dml.SWRecordPK, java.lang.Long, java.util.Date, java.util.List, java.util.List, java.util.List) SWAttributeHistoryWriter.addHistoryData} method.
Functionality activities can be temporarily stopped using usual setEnabled(boolean)
method:
SWAttributeHistoryFunctionality.setEnabled(false);//suspend roDataReading interception //do whatever; adding and removing columns to/from table won't break the things down SWAttributeHistoryFunctionality.setEnabled(true);//resume roDataReading interception
There are two ways to get rid of history data: either drop a target table (via SWDictionaryDDL
) or
kill the attribute history functionality:
//drop target table SWDictionaryDDLHome dictionaryDDLHome; SWDictionaryDDL dictionaryDDL; dictionaryDDLHome = (SWDictionaryDDLHome) PortableRemoteObject.narrow( new InitialContext.lookup("dictionary/SWDictionaryDDL"), SWDictionaryDDLHome.class); dictionaryDDL = dictionaryDDLHome.create(); dictionaryDDL.dropTable (PROJECT_ID,table.getName()); dictionaryDDL.remove(); //or kill history functionality: SWFunctionalitiesRemoverHome functionalitiesRemoverHome; SWFunctionalitiesRemover remover; functionalitiesRemoverHome = (SWFunctionalitiesRemoverHome) PortableRemoteObject.narrow( new InitialContext().lookup("functionalities/SWFunctionalitiesRemover"), SWFunctionalitiesRemoverHome.class); remover = functionalitiesRemoverHome.create(); remover.removeFunctionality(attributeHistoryFunctionality); //don't call attributeHistoryFunctionality.remove() directly! remover.remove();
Here is the UML diagram that shows key elements of the attribute history functionality.
{@link com.supportwizard.functionalities.attributehistory.SWAttributeHistoryFunctionalityLogic SWAttributeHistoryFunctionalityLogic}
intercepts recordRemoving
and roDataReading
events. Here are sequence diagrams for
Record removing and
Data reading events.
I think everything is rather simple and self-describing. Please email me if there are some incomprehensibilities,
I will immediately update the documentation.