Class AbstractWALDAO<DATATYPE>

  • Type Parameters:
    DATATYPE - The data type to be serialized
    All Implemented Interfaces:
    com.helger.commons.log.IHasConditionalLogger, IAutoSaveAware, IDAO
    Direct Known Subclasses:
    AbstractMapBasedWALDAO

    @ThreadSafe
    public abstract class AbstractWALDAO<DATATYPE>
    extends AbstractDAO
    Base class for a simple DAO using write ahead logging (WAL).
    Author:
    Philip Helger
    • Field Detail

      • DEFAULT_WAITING_TIME

        public static final Duration DEFAULT_WAITING_TIME
      • WRITE_XWS

        public static final com.helger.xml.serialize.write.IXMLWriterSettings WRITE_XWS
      • WAL_XWS

        public static final com.helger.xml.serialize.write.IXMLWriterSettings WAL_XWS
    • Method Detail

      • getIO

        @Nonnull
        protected final com.helger.commons.io.relative.IFileRelativeIO getIO()
        Returns:
        The file-relative IO as passed in the constructor. Never null.
      • getFilenameProvider

        @Nonnull
        public final Supplier<String> getFilenameProvider()
        Returns:
        The filename provider used internally to build filenames. Never null.
      • onInit

        @Nonnull
        @OverrideOnDemand
        protected com.helger.commons.state.EChange onInit()
        Custom initialization routine. Called only if the underlying file does not exist yet. This method is only called within a write lock!
        Returns:
        EChange.CHANGED if something was modified inside this method
      • onRead

        @Nonnull
        @MustBeLocked(WRITE)
        protected abstract com.helger.commons.state.EChange onRead​(@Nonnull
                                                                   com.helger.xml.microdom.IMicroDocument aDoc)
        Fill the internal structures with from the passed XML document. This method is only called within a write lock!
        Parameters:
        aDoc - The XML document to read from. Never null.
        Returns:
        EChange.CHANGED if reading the data changed something in the internal structures that requires a writing.
      • getSafeFile

        @Nonnull
        protected final File getSafeFile​(@Nonnull
                                         String sFilename,
                                         @Nonnull
                                         IDAO.EMode eMode)
                                  throws DAOException
        Get a File object for the specified filename that can perform the respective operation indicated by the "mode" parameter.
        Parameters:
        sFilename - Filename to use. May not be null.
        eMode - The access mode to be used. May not be null.
        Returns:
        The created and checked File if everything is fine, otherwise an exception is thrown.
        Throws:
        DAOException - If the requested access mode cannot be provided.
      • triggerExceptionHandlersRead

        protected static void triggerExceptionHandlersRead​(@Nonnull
                                                           Throwable t,
                                                           boolean bIsInitialization,
                                                           @Nullable
                                                           File aFile)
        Trigger the registered custom exception handlers for read errors.
        Parameters:
        t - Thrown exception. Never null.
        bIsInitialization - true if this happened during initialization of a new file, false if it happened during regular reading.
        aFile - The file that was read. May be null for in-memory DAOs.
      • getDataTypeClass

        @Nonnull
        protected final Class<DATATYPE> getDataTypeClass()
        Returns:
        The implementation class as specified in the constructor. Never null.
      • convertWALStringToNative

        @Nullable
        @OverrideOnDemand
        @IsLocked(WRITE)
        protected DATATYPE convertWALStringToNative​(@Nonnull
                                                    String sElement)
        This method is used upon recovery to convert a stored object to its native representation. If you overwrite this method, you should consider overriding convertNativeToWALString(Object) as well.
        Parameters:
        sElement - The string representation to be converted. Never null.
        Returns:
        The native representation of the object. If the return value is null, the recovery will fail with an exception!
      • onBetweenReadAndWAL

        @OverrideOnDemand
        @IsLocked(WRITE)
        protected void onBetweenReadAndWAL​(@Nonnull
                                           com.helger.xml.microdom.IMicroDocument aDoc)
        Called between initial read and WAL handling.
        Parameters:
        aDoc - The read document. Never null
      • onRecoveryErrorConvertToNative

        @OverrideOnDemand
        protected void onRecoveryErrorConvertToNative​(@Nonnull
                                                      EDAOActionType eActionType,
                                                      @Nonnegative
                                                      int i,
                                                      @Nonnull
                                                      String sElement)
        This method is called, when the conversion from the read XML string to the native type failed. By default an error message is logged and processing continues.
        Parameters:
        eActionType - The action type to recover. May not be null
        i - The index of the element to recover. Always ≥ 0.
        sElement - The string read from the WAL file that could not be recovered.
        Since:
        9.1.6
      • onRecoveryCreate

        @IsLocked(WRITE)
        protected abstract void onRecoveryCreate​(@Nonnull
                                                 DATATYPE aElement)
        Called when a recovery is needed to create a new item.
        Parameters:
        aElement - The element to be created. Never null.
      • onRecoveryUpdate

        @IsLocked(WRITE)
        protected abstract void onRecoveryUpdate​(@Nonnull
                                                 DATATYPE aElement)
        Called when a recovery is needed to update an existing item.
        Parameters:
        aElement - The element to be updated. Never null.
      • onRecoveryDelete

        @IsLocked(WRITE)
        protected abstract void onRecoveryDelete​(@Nonnull
                                                 DATATYPE aElement)
        Called when a recovery is needed to delete an existing item.
        Parameters:
        aElement - The element to be deleted. Never null.
      • initialRead

        protected final void initialRead()
                                  throws DAOException
        Call this method inside the constructor to read the file contents directly. This method is write locking internally. This method performs WAL file reading upon startup both after init as well as after read!
        Throws:
        DAOException - in case initialization or reading failed!
      • onFilenameChange

        @OverrideOnDemand
        @MustBeLocked(WRITE)
        protected void onFilenameChange​(@Nullable
                                        String sPreviousFilename,
                                        @Nonnull
                                        String sNewFilename)
        Called after a successful write of the file, if the filename is different from the previous filename. This can e.g. be used to clear old data.
        Parameters:
        sPreviousFilename - The previous filename. May be null.
        sNewFilename - The new filename. Never null.
      • createWriteData

        @Nonnull
        @MustBeLocked(WRITE)
        protected abstract com.helger.xml.microdom.IMicroDocument createWriteData()
        Create the XML document that should be saved to the file. This method is only called within a write lock!
        Returns:
        The non-null document to write to the file.
      • modifyWriteData

        @OverrideOnDemand
        @MustBeLocked(WRITE)
        protected void modifyWriteData​(@Nonnull
                                       com.helger.xml.microdom.IMicroDocument aDoc)
        Modify the created document by e.g. adding some comment or digital signature or whatsoever.
        Parameters:
        aDoc - The created non-null document.
      • getXMLWriterSettings

        @Nonnull
        @OverrideOnDemand
        protected com.helger.xml.serialize.write.IXMLWriterSettings getXMLWriterSettings()
        Returns:
        The IXMLWriterSettings to be used to serialize the data.
      • getLastFilename

        @Nullable
        public final String getLastFilename()
        Returns:
        The filename to which was written last. May be null if no wrote action was performed yet.
      • triggerExceptionHandlersWrite

        protected static void triggerExceptionHandlersWrite​(@Nonnull
                                                            Throwable t,
                                                            @Nonnull
                                                            String sErrorFilename,
                                                            @Nullable
                                                            com.helger.xml.microdom.IMicroDocument aDoc)
        Trigger the registered custom exception handlers for read errors.
        Parameters:
        t - Thrown exception. Never null.
        sErrorFilename - The filename tried to write to. Never null.
        aDoc - The XML content that should be written. May be null if the error occurred in XML creation.
      • getWALXMLWriterSettings

        @Nonnull
        @OverrideOnDemand
        protected com.helger.xml.serialize.write.IXMLWriterSettings getWALXMLWriterSettings()
        Returns:
        The IXMLWriterSettings to be used to serialize the data.
      • getWaitingTime

        @Nonnull
        public Duration getWaitingTime()
        Returns:
        The waiting time used before the file is effectively written. Never null. Default value is 10 seconds.
      • setWaitingTime

        protected void setWaitingTime​(@Nonnull
                                      Duration aWaitingTime)
        Set the waiting time used before the file is effectively written. Default value is 10 seconds. Setting the value to a duration of 0 means that the write ahead is effectively disabled.
        Parameters:
        aWaitingTime - The waiting time to be used. May not be null.
      • markAsChanged

        @MustBeLocked(WRITE)
        @OverridingMethodsMustInvokeSuper
        protected void markAsChanged​(@Nonnull
                                     DATATYPE aModifiedElement,
                                     @Nonnull
                                     EDAOActionType eActionType)
        This method must be called every time something changed in the DAO. It triggers the writing to a file if auto-save is active. This method must be called within a write-lock as it is not locked!
        Parameters:
        aModifiedElement - The modified data element. May not be null.
        eActionType - The action that was performed. May not be null.
      • writeToFileOnPendingChanges

        public final void writeToFileOnPendingChanges()
        In case there are pending changes write them to the file. This method is write locked!
      • getInitCount

        @Nonnegative
        public int getInitCount()
        Returns:
        The number of times this DAO was initialized. Always ≥ 0. Usually this field is not persistent and only is valid until the application ends.
      • getLastInitDateTime

        @Nullable
        public final LocalDateTime getLastInitDateTime()
        Returns:
        The last time this DAO was initialized (without error). May be null if it wasn't read before. Usually this field is not persistent and only is valid until the application ends.
      • getReadCount

        @Nonnegative
        public int getReadCount()
        Returns:
        The number of times this DAO was initialized. Always ≥ 0. Usually this field is not persistent and only is valid until the application ends.
      • getLastReadDateTime

        @Nullable
        public final LocalDateTime getLastReadDateTime()
        Returns:
        The last time this DAO was read (without error). May be null if it wasn't read before. Usually this field is not persistent and only is valid until the application ends.
      • getWriteCount

        @Nonnegative
        public int getWriteCount()
        Returns:
        The number of times this DAO was initialized. Always ≥ 0. Usually this field is not persistent and only is valid until the application ends.
      • getLastWriteDateTime

        @Nullable
        public final LocalDateTime getLastWriteDateTime()
        Returns:
        The last time this DAO was written (without error). May be null if it wasn't written before. Usually this field is not persistent and only is valid until the application ends.