A plugin host should be cheap to configure: registering a plugin should not initialize work that may never run. Instead, the host stores a creator under each registration name. That creator builds its plugin on the first run, then keeps the same instance for later runs.
The plugin products and PluginHost registry are already implemented in the starter code. Complete only the creator family:
PluginCreator is the abstract creator. It declares label() and the factory method createPlugin().run(text) lazily creates one plugin, includes its initialization line only on the first run, then appends the execution line and Plugin "<Label>" executed..runs() returns how many times this creator has run its plugin.builtCount() is 0 before the first run and 1 afterwards.LoggerCreator, ValidatorCreator, and TransformerCreator return their matching pre-implemented products and expose the labels "Logger", "Validator", and "Transformer".The supplied host rejects duplicate names and unknown kinds, preserves registration order, and creates a separate creator for every successful registration. That last detail matters: registering two logger names must produce two independently initialized logger plugins.
The three kinds behave differently:
Kind | Label | Initialisation line | Execution line |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
The validator reports is invalid. instead of is valid. when the text is empty. The tests call only PluginHost; your creator classes provide the lazy construction and per-registration state that its pre-written registry expects.
Input:
Output:
Explanation: One registration, one run. The plugin does not exist until the run needs it, so that run reports the initialisation line and the created count reaches 1.
Input:
Output:
Explanation: Two names both registered as loggers get two creators and therefore two separate plugins, so both first runs report initialisation and the created count reaches 2.
name, kind and text contain letters, digits and spaces only.0 <= text.length <= 5020 names are registered in one host.100 calls in total are made across all methods.Full marks when PluginCreator is abstract, declares createPlugin as the factory method, and each concrete creator returns only its matching pre-implemented plugin while exposing the required label. Lose points heavily when product selection is moved into shared run logic or the supplied PluginHost.
Full marks when each creator builds one plugin on its first run, initializes it once, reuses it later, and writes the execution and closing sequence once on the base creator. Lose points when registration-time construction is introduced, every run creates a product, or initialization repeats.
Full marks when each creator instance maintains independent run and built counts, label returns without building, and the output lines match exactly. Lose points for sharing state between registrations, modifying the supplied products or PluginHost, or printing to stdout.
Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.
| Call | Returns |
|---|---|
| new PluginHost() | null |
| registerPlugin("logger", "logger") | true |
| run("logger", "Hello World") | ["[Logger] Initialized.","[Logger] Logging: Hello World","Plugin \"Logger\" executed."] |
| runCount("logger") | 1 |
| pluginsCreated() | 1 |
One registration, one run. The plugin does not exist until the run needs it, so that run reports the initialisation line and the created count reaches 1.
Run checks these cases. Submit also runs a larger hidden set.

