Class ModuleCapabilities
modules:<id>@<X.Y.Z> capability names an UltiCloud protocol v2 hello declares
for the modules that answer module.request; internal, not for module use.
One name is produced per module owning at least one responder, and none for a module that owns
none — the gateway sends a module's request only to a plugin that declared that module's
capability (D-24, contract answer 11). The id is the module's UltiCloud identifier -- its
catalogue identifier, which is its identify-string lower-cased (ModuleIds), not its
plugin.yml name (PanelResponderRegistry.moduleIdentifierOf(String); 22-26 fix round,
backend contract answer of 2026-10-27). A module whose identifier cannot be derived is skipped with
one WARNING rather than mangled into something the gateway would route wrongly.
The version is supplied by the caller from the module's own plugin.yml version and cut
to its first three numeric parts, so 1.2.0-beta becomes 1.2.0, 2 becomes
2.0.0, and a version with no digits at all becomes 0.0.0. The list is sorted by id
so repeated calls and repeated connections declare exactly the same names in the same order.
The contract caps a hello at 64 capability names in total, which the framework's own
capabilities also draw from. This class never returns more than 64; the caller that adds the
framework's own capabilities keeps the combined list within the cap.
hello also caps one capability name at 96 characters. A module name long enough to
push modules:<id>@<version> past that would make the whole hello schema-invalid,
and the gateway answers an invalid frame with a 4400 close — every panel feature down because of
one module's name. Such a module is skipped with one WARNING naming it, exactly like a name that
cannot form an identifier.
- Since:
- 6.3.1
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final Patternprivate static final Logger(package private) static final intThe contract'shellolimit on one capability name.(package private) static final intThe contract'scapabilitiesMaxItems; the framework's own names share this cap.private static final String -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionnames(PanelResponderRegistry registry, Function<String, String> moduleVersionByName) The capability names to declare for every module that currently owns a responder.(package private) static StringThe first three numeric parts of a plugin version, padded with zeros to a fullX.Y.Z.private static StringwithoutLeadingZeros(String digits)
-
Field Details
-
MAX_NAMES
static final int MAX_NAMESThe contract'scapabilitiesMaxItems; the framework's own names share this cap.- See Also:
-
MAX_CAPABILITY_LENGTH
static final int MAX_CAPABILITY_LENGTHThe contract'shellolimit on one capability name.- See Also:
-
NAME_PREFIX
- See Also:
-
DIGITS
-
LOGGER
-
-
Constructor Details
-
ModuleCapabilities
private ModuleCapabilities()
-
-
Method Details
-
names
static List<String> names(PanelResponderRegistry registry, Function<String, String> moduleVersionByName) The capability names to declare for every module that currently owns a responder.- Parameters:
registry- the registry holding module respondersmoduleVersionByName- the module's own plugin version by owner module name, as recorded in itsplugin.yml; anullresult is treated as a version with no digits- Returns:
- an unmodifiable list sorted by module id, at most
MAX_NAMESlong; empty when no module owns a responder
-
version
The first three numeric parts of a plugin version, padded with zeros to a fullX.Y.Z. Leading zeros inside a part are dropped, so01.2is1.2.0: the contract's semver core forbids them. -
withoutLeadingZeros
-