EN · DE · RU · FR · ES

#2771: LessWicketApplicationInstantiator.java

projectforge-wicket/src/main/java/de/micromata/less/LessWicketApplicationInstantiator.java LESS CSS Compilation Engine (Wicket Integration) · projectforge-wicket/src/main/java/de/micromata/less/LessWicketApplicationInstantiator.java 206 lines · 116 code · 62 comments · 28 blank
The core LESS-to-CSS compilation orchestrator for ProjectForge's Wicket web layer. This singleton class integrates the lesscss-java compiler into Wicket's application lifecycle: it locates .less source files on the classpath, compiles them to CSS on the filesystem, mounts the compiled CSS as a versioned Wicket resource (using LessResourceReference), and — in development mode — registers filesystem watchers that automatically recompile when any .less source file changes. The compiled CSS filename includes the server startup timestamp as a cache-busting version marker (projectforge-version-{timestamp}.css).

Architecture

Application Lifecycle Integration

The class implements Serializable and maintains a static instance field. During Wicket application startup, an instance is created with the source .less path, target .css path, and a filesystem baseDir. The instantiate() method is called, which:

  1. Resolves the LESS source file from the classpath via Spring's ClassPathResource
  2. Optionally compiles the LESS to CSS (controlled by the compileCss flag — useful for production where CSS should be pre-compiled)
  3. Creates a LessResourceReference for the compiled output
  4. Mounts the resource on Wicket's resource registry with a versioned path
  5. In development mode, attaches filesystem modification watchers to every imported LESS file

Development Mode Watchers

When WebConfiguration.isDevelopmentMode() returns true, the class leverages Wicket's built-in IModificationWatcher infrastructure to monitor the main LESS source and all its @import dependencies. When any file changes, the watcher triggers a recompilation — developers see CSS changes immediately without restarting the server. The watcher covers the entire transitive import graph via mainLessSource.getImports().values().

Cache Busting Strategy

The method encodePathWithCachingStrategy replaces .css with -version-{startTime}.css in the resource path. The timestamp (WicketApplication.getStartTime()) changes on each server restart, effectively busting browser caches after deployments. The prefix -version- is deliberately different from Wicket's default -ver- to avoid collisions with Wicket's internal resource versioning.

Static Rendering Helper

The static method renderCompiledCssResource(IHeaderResponse) is the entry point called by page templates to include the compiled CSS in HTML headers. It renders a CssReferenceHeaderItem pointing to the mounted resource. If the instantiator hasn't been initialized (the static instance is null), it logs an error — this is a fail-safe for pages rendered before the LESS compilation completes.

Git History

CommitWhat changed
868d6abb7 through 4a6390e11Six commits spanning copyright year updates (2021→2026) and a Wicket 8 migration merge (4548710df). The copyright updates follow the annual header sweep pattern. The Wicket 8 migration commit (4a6390e11) is a merge from feature/wicket8 into develop — while the merge diff itself may not show changes in this specific file, the branch brought significant API changes across the wicket module. The class logic itself has been stable; all history entries are infrastructure changes rather than feature modifications.