Class OperatorFiles

java.lang.Object
com.ultikits.ultitools.config.OperatorFiles

public final class OperatorFiles extends Object
Writes named keys of an operator-editable YAML file that a module manages on an operator's behalf - a kit file, a menu file - and nothing else.

Such files are created by the operator (or by the module on the operator's explicit create action) and edited by hand. The maintainer's rule for them (2026-10-04, "what code may write, by file type") is that an explicit edit - a kit editor saving a kit's items - writes only the edited part: comments, other keys, unknown keys and values the module itself cannot use stay exactly as the operator wrote them. A module therefore reads the file, decides what to change, and writes only those whole keys:


 OperatorFiles.Snapshot snapshot = OperatorFiles.read(kitFile);
 // ... parse snapshot.getText() with any YAML reader ...
 OperatorFiles.WriteResult result = OperatorFiles.write(snapshot,
         Collections.singletonMap(Collections.singletonList("items"), serializedItems));
 

Why it cannot change anything else. The write goes through the framework's configuration write gate: it owns only the named keys, renders the file, and publishes it only when every line outside those keys - comments, other keys, layout, quoting, a value the module cannot use - is byte-identical to the file as read, and only while the file still holds exactly the bytes of the snapshot (an edit saved after read is never overwritten). Otherwise nothing is written and the result says why (OperatorFiles.WriteResult.FILE_CHANGED or OperatorFiles.WriteResult.REFUSED, the latter with one WARNING in the server log naming the file, the keys and the reason, never a value). Publication is atomic. A key path is a list of whole keys, so a key containing . is one key.

What it does not do. It never creates, deletes or renames a file: read requires an existing file, and write touches only the file of its snapshot and refuses when that file is gone. Values must be plain data (strings, numbers, booleans, null, and lists and string-keyed maps of those); a Bukkit object such as an ItemStack, a UUID or any other type is refused before anything is read or written - serialize it first. This is not a general file API: it writes YAML keys of a file that already exists (a crash-safe file API for modules is UltiKits/UltiTools-Reborn#545, a later feature), and it is not for a module's @ConfigEntity files, which have their own save rules.

Since:
6.3.0
  • Constructor Details

    • OperatorFiles

      private OperatorFiles()
  • Method Details

    • read

      public static OperatorFiles.Snapshot read(File file) throws IOException
      Reads an existing file. Nothing is written.
      Parameters:
      file - the file to read
      Returns:
      its text and fingerprint
      Throws:
      IOException - if the file does not exist, cannot be read, or is not valid UTF-8
    • write

      public static OperatorFiles.WriteResult write(OperatorFiles.Snapshot readAt, Map<List<String>,Object> values) throws IOException
      Writes values - each a whole key path and its new value - into the snapshot's file and changes nothing else, only while the file still holds the snapshot's bytes (see the class description for why nothing else can change). A key the file lacks is inserted. Must not be called for a file a @ConfigEntity manages.
      Parameters:
      readAt - the snapshot the change was decided on
      values - key path (a list of whole keys, at least one) to plain-data value
      Returns:
      what happened; OperatorFiles.WriteResult.UNCHANGED when values is empty
      Throws:
      IllegalArgumentException - if a key path is empty or holds null, or a value is not plain data - checked before the file is read again, so nothing is written
      IOException - if publishing fails; the file then holds its old bytes (a failed in-place fallback is put back from its framework backup first) - only when even that fails does it hold part of the new content, with one SEVERE naming the file and the framework backup kept beside it
    • sha256

      private static String sha256(byte[] bytes)