Universal Java utility library. Compatible with JDK 8+.
<dependency>
<groupId>cz.bliksoft.java</groupId>
<artifactId>common-java-utils</artifactId>
<version>0.6</version>
</dependency>Most heavyweight features are optional — the library compiles without them and you add only what you need:
| Feature | Add to your POM |
|---|---|
| Freemarker templating | dependency-management-8-freemarker BOM |
| Log4j 2 | dependency-management-8-log4j BOM |
| Excel / Word (OOXML) | dependency-management-8-ooxml BOM |
| JAXB | dependency-management-8-jaxb BOM |
| WS interface + JAXB | dependency-management-8-servicedef BOM |
| WS client | dependency-management-8-client BOM |
| WS server | dependency-management-8-service BOM |
| QR code generation | com.google.zxing:core |
| mDNS/Bonjour announcement | org.jmdns:jmdns |
Detailed guides in doc/:
app ·
context ·
modules ·
xml-filesystem ·
services ·
freemarker ·
database ·
math ·
ws ·
classloader ·
environment-utils ·
image-utils
Hierarchical, event-driven state container. Values are stored in a tree of Context nodes and observed via typed listeners. Changes propagate up the tree automatically.
| Class | Purpose |
|---|---|
Context |
Tree node; stores values by type (addValue) or key (put). Static getRoot() / getCurrentContext() for global access. |
SingleContext<T> |
Leaf node holding one typed value; bindable to a JList or JTree selection. |
EmptyContext |
Plain container node with no value storage. |
AbstractContextListener<T> |
Base for observers; implement fired(ContextChangedEvent<T>). Supports enable/disable and level-crossing limits. |
ContextBoundary |
Listener that blocks event propagation past its attachment point. |
Holders are special Context nodes that manage which child context is currently "active". All three extend SingleContextHolder and delegate value reads to the active child.
SingleContextHolder — holds at most one child; the child can be replaced atomically.
SingleContextHolder holder = new SingleContextHolder("my holder");
holder.replaceContext(myContext);
Context active = holder.getContext();StackedContextHolder — push/pop stack; the top entry is always the active child.
StackedContextHolder stack = new StackedContextHolder("screens");
stack.push(loginContext);
stack.push(dashboardContext); // dashboard is now active
stack.pop(); // back to loginMapContextHolder<T, C> — named map of contexts; select(key) makes one active.
MapContextHolder<String, EmptyContext> holder = new MapContextHolder<>("tabs");
holder.put("home", new EmptyContext("home tab"));
holder.put("settings", new EmptyContext("settings tab"));
holder.select("home"); // home is now active
String current = holder.getSelectedKey(); // "home"
holder.deselect();All three holders include inactive entries in dump() output for debugging.
AbstractContextListener<MyService> listener = new AbstractContextListener<MyService>(MyService.class, "svc watcher") {
@Override
public void fired(ContextChangedEvent<MyService> event) {
MyService svc = event.getNewValue(); // null if removed
}
};
context.addContextListener(listener);context.fireEvent(new MyEvent()); // any thread
context.fireGUIEvent(new MyEvent()); // enforces EDTSPI-based plugin loader. Modules are discovered via java.util.ServiceLoader.
Implement IModule (or extend ModuleBase):
public class MyModule extends ModuleBase {
@Override public void init() { /* called first */ }
@Override public void install() { /* called second */ }
@Override public void cleanup() { /* on shutdown */ }
}Register in META-INF/services/cz.bliksoft.javautils.modules.IModule.
Loading lifecycle:
Modules.loadModules(); // discover and instantiate
Modules.initModules(); // call init() on each
Modules.installModules(); // call install() on eachModules can contribute an XML virtual filesystem descriptor via getFilesystemXml() and control load order via getModuleLoadingOrder().
BSApp builds an application skeleton on top of the modules framework: lifecycle (init() → start()/startConsole(), vetoable shutdown via TryCloseEvent), layered XML properties (global {workingDir}/.{appName}/settings.xml + local ~/.{appName}/settings.xml, with per-environment key prefixes), an application event-dispatch thread (executeLater), and a pluggable permission/session model (Permissions, SessionManager, UserInfo). Requires Log4j 2.
BSApp.setAppName("myapp");
BSApp.init();
BSApp.startConsole(); // blocks; 'q' + Enter quitsSee doc/app.md for the full reference.
Modules contribute XML descriptors that are merged at runtime into a single virtual FileSystem of FileObject nodes — used for configuration, class wiring, and translations.
FileSystem.getDefault().importXml(myModule.getFilesystemXml(), "MyModule");
FileSystem.loadTranslations(); // once, after all modules are loaded
FileObject config = FileSystem.getFile("config/database");
String url = config.getAttribute("url", "jdbc:default");Descriptors are plain XML (META-INF/XmlFilesystem.xsd):
<root xmlns="http://bliksoft.cz/XmlFilesystem">
<file name="config" type="folder">
<file name="database" type="dbConfig">
<attribute name="url" value="${DB_URL}"/>
</file>
</file>
<include path="/etc/optional-extra.xml"/>
<require path="/etc/mandatory.xml"/>
<symlink name="db" path="config/database"/>
</root>Writable nodes: adding mode="rw" to a top-level <include>/<require> loads its <file>/<symlink> roots as WritableFileObjects, which support setAttribute, addChild, getCreateFile, etc., and can be persisted back to their source file with save().
See doc/xml-filesystem.md for the full reference, including localization and the writable-filesystem extension.
FreemarkerGenerator wraps Apache Freemarker with a set of built-in extensions and a consistent API.
// from classpath (relative to MyClass)
FreemarkerGenerator gen = new FreemarkerGenerator(MyClass.class);
String result = gen.generate("report.ftl", dataObject); // data exposed as ${data}
// to file
gen.generate("report.ftl", dataObject, new File("output.html"));
// inject extra variables
gen.setVariable("title", "My Report");Selected built-in template variables (always available):
| Variable | What it does |
|---|---|
regroup |
Groups a List<Map> by key columns into a nested Map |
reindex |
Like regroup but assumes unique keys (last level is the row directly) |
code128 / code128width |
Code128 barcode SVG encoding and width calculation |
Base64QR |
QR code as Base64 image (requires ZXing) |
prettyXML / parseXML |
Pretty-print or parse XML strings |
formatAsHTML / TXTTOHTML |
HTML-escape plain text |
StringBuilder |
Capture a template block into a string variable |
variableCache |
In-template key-value store (set/get/add/put) |
GUIPrompt / CMDPrompt |
Prompt user for input (Swing dialog or stdin) |
SQL queries in templates (add manually):
gen.addExtension("Query", new Query(connectionProvider));Then in the template: <#assign rows = Query("SELECT ...")>.
Custom type wrappers:
// before the first FreemarkerGenerator is created:
ObjectWrapperRegister.addConverter(MyType.class, obj -> obj.toString());// Implement IDBConnectionProvider and register it:
DBConnectionProvidersRegister.register("mydb", myProvider);
// Retrieve:
IDBConnectionProvider p = DBConnectionProvidersRegister.get("mydb");
try (Connection c = p.getConnection()) { ... }Built-in implementations: MySQLConnection, MariaDbConnection, OracleDbConnection (require the respective JDBC driver on the classpath). See doc/database.md.
Lightweight embedded HTTP server and handler helpers:
BSHttpServer— embeddable HTTP(S) server (com.sun.net.httpserverwrapper); handlers attachable at runtime, optional thread pool, TLS/mutual TLS from code or XML config, mDNS announcement viaregisterMdnsService(name). Can be shared app-wide as a singleton — seedoc/services.md.MdnsRegistrar— announces services on the LAN via mDNS/Bonjour (requiresorg.jmdns:jmdns).DefaultFileHTTPHandler— serves files from a directory.DefaultResourceHTTPHandler— serves classpath resources.SystemReportHTTPHandler— exposes a simple system-info endpoint.MultiPart— builds multipart/form-data request bodies.IPUtils— local IP address discovery.
JAXB date/time adapters (reference in bindings.xml):
| Adapter | Java type |
|---|---|
LocalDateAdapter |
LocalDate |
LocalDateTimeAdapter |
LocalDateTime |
LocalTimeAdapter |
LocalTime |
OffsetDateTimeAdapter |
OffsetDateTime |
ZonedDateTimeAdapter |
ZonedDateTime |
BigDecimalAdapter |
BigDecimal |
SimpleObjectMapAdapter |
Map<String,Object> as typed <integer/string/boolean/float/local-date/…> elements with name/value attributes; custom types via registerTypeHandler |
XPath extensions (cz.bliksoft.javautils.xml.xpath) — custom functions usable in XPath expressions. Register once with XmlUtils.registerXPathExtensions() (binds namespace prefix bsExt → http://bliksoft.cz; overloads accept a custom prefix or namespace context), then compile expressions via XmlUtils.compileXPath(...):
XmlUtils.registerXPathExtensions();
String s = XmlUtils.getResultText(
XmlUtils.compileXPath("bsExt:formatDate(bsExt:now(), 'yyyy-MM-dd')").evaluate(doc));| Function | Purpose |
|---|---|
choose(cond, ifTrue, ifFalse) |
Ternary operator |
ifElseIf(cond1, res1 [, cond2, res2, …][, elseRes]) |
Chained conditions; odd trailing argument is the else value |
map(input, val1, res1 [, val2, res2, …][, default]) |
Value-to-value mapping; even trailing argument is the default |
default(value, fallback) |
Fallback when the value is empty or missing |
first(a, b, …) |
First non-empty argument as text |
join(separator, a, b, …) |
Joins non-empty text values with a separator |
format(pattern, args…) |
MessageFormat-style formatting |
sprintf(format, args…) |
String.format-style formatting |
formatNumber(value, pattern) |
DecimalFormat number formatting |
formatDate(value, pattern) |
DateTimeFormatter formatting; accepts temporal objects, Date, epoch millis, or ISO strings |
now() |
Current time as epoch milliseconds (feed into formatDate) |
uuid() |
Random UUID string |
log(...) |
Logs a message and passes a value through |
var(namespace, name) |
Reads a value from the static XPathVarCache (set from Java) |
| Class | Highlights |
|---|---|
StringUtils |
hasText, format (MessageFormat shorthand), ellipsis |
NumericUtils |
Numeric parsing and conversion helpers |
BooleanUtils |
Lenient toBoolean(Object) coercion (numbers, strings, null-safe) |
DateUtils |
Date/time formatting and parsing |
GeneralUtils |
Miscellaneous object utilities |
ClasspathUtils |
Classpath resource loading |
Base64Utils |
Base64 encode/decode |
CryptUtils |
AES / hash helpers |
SystemUtils |
OS and JVM info |
PropertiesUtils |
Properties file loading |
TimestampedObject<T> |
Value wrapper with a LocalDateTime timestamp |
LimitedList<T> |
ArrayList capped at a configurable maximum size |
HashUUIDCreator |
Deterministic UUID from arbitrary input |