Class StaticThemeInstaller

java.lang.Object
org.codelibs.fess.theme.StaticThemeInstaller

public class StaticThemeInstaller extends Object
Installs static themes from uploaded ZIP archives.

The installer enforces security guards against ZipSlip, oversized extractions, excessive entry counts, and compression-ratio bombs. Successful extractions are promoted into the active themes directory via an atomic directory rename so partial installs never become visible to readers.

Lifecycle:

  1. Stream the archive into a staging directory under themes/.staging-<uuid>.
  2. Validate the embedded theme.yml via ThemeManifest.
  3. If a theme with the same name exists, rename it to an .attic- backup so a failed promotion can roll back. The attic's lastModifiedTime is reset to "now" right after the rename so the theme.upload.attic.retention.days window starts from the install moment, not the original theme directory's age.
  4. Atomically rename the staging directory to themes/<name> and reload the ThemeRegistry.
  5. On success the attic backup is retained per theme.upload.attic.retention.days (default 7 days) and aged out by cleanupOldAtticDirs(Path); it is no longer eagerly deleted.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static class 
    Raised on any failure during ZIP validation or extraction.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected org.codelibs.fess.mylasta.direction.FessConfig
    Injected Fess configuration used to resolve limits and the themes directory.
    protected ThemeRegistry
    Injected theme registry reloaded after successful install/delete.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Default constructor.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    delete(String name)
    Removes the static-theme directory atomically.
    void
    Wire configuration keys from FessConfig and sweep JVM-crash orphan staging directories at container startup.
    void
    Installs a theme from the supplied ZIP stream.
    protected void
    moveDir(Path source, Path dest)
    Atomically moves source to dest.

    Methods inherited from class java.lang.Object

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

    • fessConfig

      protected org.codelibs.fess.mylasta.direction.FessConfig fessConfig
      Injected Fess configuration used to resolve limits and the themes directory.
    • themeRegistry

      protected ThemeRegistry themeRegistry
      Injected theme registry reloaded after successful install/delete.
  • Constructor Details

    • StaticThemeInstaller

      public StaticThemeInstaller()
      Default constructor. Configured limits are read from FessConfig during init(); falls back to built-in defaults when DI is absent.
  • Method Details

    • init

      @PostConstruct public void init()
      Wire configuration keys from FessConfig and sweep JVM-crash orphan staging directories at container startup.

      Hardcoded field values above serve as defaults when FessConfig is absent (e.g. unit tests where DI is not set up).

    • installZip

      public void installZip(InputStream zipStream)
      Installs a theme from the supplied ZIP stream.
      Parameters:
      zipStream - the archive content; the caller retains ownership of closing the underlying stream
      Throws:
      StaticThemeInstaller.InstallException - if validation, extraction, or promotion fails
    • delete

      public void delete(String name)
      Removes the static-theme directory atomically.

      Refuses when (a) the name fails the spec §4.2 regex (^[a-z0-9][a-z0-9_-]{0,63}$), (b) the theme is the currently active default (per the configured probe or ThemeRegistry.resolveActiveTheme(String)), or (c) the directory does not exist under the themes root.

      Successful deletion atomically renames the directory to themes/.attic-<name>-<timestamp>/ — preserving the §4.4 7-day retention semantics — and reloads the ThemeRegistry.

      Parameters:
      name - the theme directory name; must match ^[a-z0-9][a-z0-9_-]{0,63}$
      Throws:
      StaticThemeInstaller.InstallException - on validation, lookup, or rename failure
    • moveDir

      protected void moveDir(Path source, Path dest) throws IOException
      Atomically moves source to dest. Falls back to a plain replacing move on filesystems that do not support ATOMIC_MOVE.

      Exposed as an instance method (rather than a static helper) so unit tests can subclass and inject failure modes to exercise the promotion/rollback paths in installZip(InputStream).

      Parameters:
      source - path to move
      dest - destination path
      Throws:
      IOException - if the move fails on the underlying filesystem