Class AtomicConfigWriter.StagedWrite

java.lang.Object
com.ultikits.ultitools.config.document.AtomicConfigWriter.StagedWrite
Enclosing class:
AtomicConfigWriter

public static final class AtomicConfigWriter.StagedWrite extends Object
A temporary file written beside its target and not yet moved over it.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private final byte[]
     
    private final IOException
     
     
    private final Path
     
    private final Path
     
    private final Path
     
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    StagedWrite(Path target, Path temporary, Path identity, AtomicConfigWriter.FileOperations files, byte[] data, IOException deferredCause)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Atomically replaces the target, or uses the backed in-place path on an eligible refusal.
    (package private) void
    Publishes the staged text as a new file, for a target that did not exist when it was read: never replaces a file that exists by then.
    boolean
    commitIfUnchanged(byte[] expected)
    Commits only while the target still holds exactly expected, re-read under the lock every config load and write holds, immediately before the replacement; otherwise the staged file is released and nothing is replaced.
    boolean
    Removes the temporary file without touching the target.
    private void
    putBack(byte[] original, Path backup, Exception failure)
    Puts the target back after its in-place write failed once it was open (#622): writes original - the bytes it held immediately before, which the forced backup holds - back in place, then removes the backup as no longer needed.
    private void
    refreshBackup(Path backup, byte[] original, FileAttribute<?>[] attributes)
    Refreshes a retained backup without exposing a partial replacement.
    private void
    replaceInPlace(byte[] replacement, IOException cause)
     
    The file this write replaces (a symbolic link already resolved).
    The temporary file holding the new content on the normal path.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

  • Method Details

    • target

      public Path target()
      The file this write replaces (a symbolic link already resolved).
      Returns:
      the target
    • temporary

      public Path temporary()
      The temporary file holding the new content on the normal path. After an eligible temporary-create refusal, this is a reserved same-directory path that may not exist; the bytes remain in memory.
      Returns:
      the temporary file
    • commit

      public void commit() throws IOException
      Atomically replaces the target, or uses the backed in-place path on an eligible refusal.
      Throws:
      IOException - if replacement fails; a failed in-place attempt puts the target back from its backup first (a AtomicConfigWriter.RestoreFailedException when that fails too, the backup then kept)
    • commitIfUnchanged

      public boolean commitIfUnchanged(byte[] expected) throws IOException
      Commits only while the target still holds exactly expected, re-read under the lock every config load and write holds, immediately before the replacement; otherwise the staged file is released and nothing is replaced. This is the last-moment check for a caller that verified its edit against bytes it read earlier: an edit saved meanwhile is kept, never overwritten.
      Parameters:
      expected - the bytes the caller read and verified its edit against
      Returns:
      whether the target was replaced
      Throws:
      IOException - if reading the target or the replacement fails (see commit())
    • replaceInPlace

      private void replaceInPlace(byte[] replacement, IOException cause) throws IOException
      Throws:
      IOException
    • putBack

      private void putBack(byte[] original, Path backup, Exception failure) throws AtomicConfigWriter.RestoreFailedException
      Puts the target back after its in-place write failed once it was open (#622): writes original - the bytes it held immediately before, which the forced backup holds - back in place, then removes the backup as no longer needed. When that fails, the backup is kept (no load deletes it any more), one SEVERE names the target and the backup and no content, and a AtomicConfigWriter.RestoreFailedException replaces the failure.
      Throws:
      AtomicConfigWriter.RestoreFailedException
    • refreshBackup

      private void refreshBackup(Path backup, byte[] original, FileAttribute<?>[] attributes) throws IOException
      Refreshes a retained backup without exposing a partial replacement.
      Throws:
      IOException
    • commitAsNewFile

      void commitAsNewFile() throws IOException
      Publishes the staged text as a new file, for a target that did not exist when it was read: never replaces a file that exists by then. The temporary file is hard-linked onto the target, which fails if the target exists; where the file system refuses links, the target is checked again immediately before a move that does not replace. The temporary name is removed either way.
      Throws:
      FileAlreadyExistsException - if a file appeared at the target; it is left as it is
      IOException - if publishing fails otherwise; no file was replaced
    • discard

      public boolean discard()
      Removes the temporary file without touching the target.
      Returns:
      whether the temporary file is gone