diff --git a/docs/1.html b/docs/1.html index 163b0bfc5..61ee0a51e 100644 --- a/docs/1.html +++ b/docs/1.html @@ -73,42 +73,42 @@
Nasdanika Capability framework allows to discover/load capabilities which meet a requirement. Capabilities are provided by CapabilityFactory create()
method. Capability factories may request other capabilities they need. As such, capabilities can be chained. Factories create CapabilityLoaders which provide Flux reactive streams of capabilities. It allows to have an infinite stream of capabilities which are consumed (and produced) as needed. Capability providers may furnish additional information about capabilities. This information can be used for filtering or sorting providers.
Nasdanika Capability framework1 allows to discover/load capabilities which meet a requirement. Capabilities are provided by CapabilityFactory create()
method. Capability factories may request other capabilities they need. As such, capabilities can be chained. Factories create CapabilityLoaders which provide Flux reactive streams of capabilities. It allows to have an infinite stream of capabilities which are consumed (and produced) as needed. Capability providers may furnish additional information about capabilities. This information can be used for filtering or sorting providers.
A non-technical example of requirement/capability chain graph is a food chain/graph. Food is a requirement. Or “I want to eat” is a requirement. Bread and, say fried eggs are two capabilities meeting/addressing the requirement. Bread requires “wheat”, “water”, and “bake” capabilities. Fried eggs require “egg”, “oil”, and “fry” capabilities. Bread capability provider may implement Vegan
marker interface which can be used for filtering. All food capabilities may implement NutritionalInformation
interface - it can be used for filtering or sorting.
A more technical example is Java ServiceLoader with service type being a requirement and an instance of the service class being a capability.
Nasdanika capability framework can operate on top of ServiceLoader
and may be thought of as a generalization of service loading. In essence, the capability framework is a backward chaining engine as shown in one of the example below.
A similar approach can be applied to other models - customer/accounts, organization or architecture model, etc.
For example, from the Internet Banking System we can generate something like “Accounts Summary Controller uses Mainframe Banking System Facade to make API calls to the Mainframe Banking System over XML/HTTPS”. “make API calls” may also be generated as “connect” or “make requests”.
In a similar fashion a number of questions/answers can be generated.
+Classes in this module allow to declaratively construct command line interfaces. It uses picocli to execute commands and capability framework to collect sub-commands and mix-ins. This way command line interfaces can be constructed top-down (default picocli functionality) - parent commands explicitly define sub-commands, and bottom-up - sub-commands are added to parent commands by the framework.
+Classes in this module allow to declaratively construct command line interfaces. It uses picocli to execute commands and capability framework to collect sub-commands and mix-ins. This way command line interfaces can be constructed top-down (default picocli functionality) - parent commands explicitly define sub-commands, and bottom-up - sub-commands are added to parent commands by the framework. Top-down construction can be done using out-the-box picocli capabilities - programmatic add and annotations. Both top-down and bottom-up construction can be done using the capability framework which allows sub-commands/mix-ins to request capabilities they need and add themselves to parent commands only if all requirements are met.
+The module provides a capability to build polymorphic CLI’s - sub-commands and mix-ins may override other sub-commands and mix-ins with the same name. This is similar to method overriding in Object-Oriented languages like Java. For example, a base CLI package may have a basic implementation of some sub-command. A derived package would add dependencies with advanced sub-commands to pom.xml
. These sub-commands would replace (override) basic sub-commands during construction of the command hierarchy.
Create a sub-class of SubCommandCapabilityFactory
and override either createCommand
or createCommands
methods. Add to module-info.java
:
In addition to the picocli way of adding sub-commands programmatically and using @Command
annotation subcommands
element this module provides a few more ways to contribute sub-commands which are explained below.
In all cases create a sub-class of SubCommandCapabilityFactory
and implement/override the following methods:
getCommandType
- used for declarative matchingcreateCommand
for imperative (programmatic) matchingdoCreateCommand
:
+@SubCommands
or @Parent
match()
as well.Add to module-info.java
:
provides org.nasdanika.capability.CapabilityFactory with <factory class>
opens <sub-command package name> to info.picocli;
opens <sub-command package name> to info.picocli, org.nasdanika.html.model.app.gen.cli;
Opening to org.nasdanika.html.model.app.gen.cli
is needed if you want to generate extended documentation (see below).
This one is similar to @Command.subcommands
- the parent command declares types of sub-commands. However:
SubCommandCapabilityFactory
’s.HelpCommand
interface or base class and all commands implementing/extending this class will be added to the parent command. If there are two commands with the same name one of them might override the other as explained below.In this case the sub-command or mix-in class are annotated with @Parent
annotation listing types of parents. The sub-command/mix-in will be added to all commands in the hierarchy which are instances of the specified parent types - exact class, interface implementation, or sub-class.
The above two ways of matching parent commands and sub-commands are handled by the SubCommandCapabilityFactory.match()
method. You may override this method or createCommand()
method to programmatically match parent path and decide whether to contribute a sub-command or not.
Create s sub-class of MixInCapabilityFactory
, implement getName()
and createMixIn()
methods. Add to module-info.java
:
Similar to sub-commands, mix-ins can be contributed top-down and bottom-up - declaratively using annotations and programmatically.
+In all cased create s sub-class of MixInCapabilityFactory
, implement/override:
getMixInType()
- for declarative matchinggetName()
createMixIn()
for imperative matching, ordoCreateMixIn()
+@MixIns
or @Parent
match()
as well.Add to module-info.java
:
provides org.nasdanika.capability.CapabilityFactory with <factory class>
opens <mix-in package name> to info.picocli;
MixInCapabilityFactory
’s.See “@Parent annotation” sub-section in “Contributing sub-commands” section above.
+The above two ways of matching parent commands and sub-commands/mix-ins are handled by the MixInCapabilityFactory.match()
method. You may override this method or createMixIn()
method to programmatically match parent path and decide whether to contribute a mix-in or not.
A command/mix-in overrides another command/mix-in if:
+Overrider
interface and returns true
from overrides(Object other)
method.@Overrides
and the other command is an instance of one of the value classes.You may annotate commands with @Description
to provide additional information in generated HTML site.
A distribution is a collection of modules contributing commands and mix-ins plus launcher scripts for different operating systems. org.nasdanika.cli
and org.nasdanika.launcher
modules are examples of building distributions as part of Maven build. Building a distribution involves two steps:
If the Maven project which builds the distribution does not contribute its own code, then the for
loop copying the jar file can be omitted.
To generate a command line which can be used from any directory use -s
(absolute) option or -P
(prefix) option set to the installation directory.
If you encounter command line length limit (8191 characters on Windows), move command options (-p
, -classpath
, -m
) to a file or use -t
option to generate just options. Then use @
syntax. For example:
@java @<installation directory>\options %*
-
TODO
-Nasdanika Command Line Interface (CLI) is a collection of Nasdanika offerings packaged as command line tools.
+Nasdanika Command Line Interface (CLI) is a suite of Nasdanika capabilities packaged as command line tools.
+To run Nasdanika CLI you’d need Java 17+. To build from sources you’d also need Maven.
+Download installation archive from the releases page. On Linux make nsd
executable: chmod a+x nsd
.
mvn clean verify
target/dist
directoryThe distribution is portable and local - it can be put to any directory, but it can only be executed from that directory. To create an installation which can be used from any directory you will need to create launcher files with absolute paths.
+nsd.bat launcher -f options-global -o nsd-global.bat -s -m org.nasdanika.launcher -c org.nasdanika.launcher.Launcher -M modules -j "@java"
+
+Add the installation to the PATH
environment variable. You may delete/rename nsd.bat
and rename nsd-global.bat
to nsd.bat
.
./nsd launcher -o nsd-global -s -m org.nasdanika.launcher -c org.nasdanika.launcher.Launcher -M modules
+
+Open nsd-global
in a text editor and add #!/bin/bash
line before the java command line. Make the file executable and add the installation directory to the path. You may remove/rename nsd
and rename nsd-global
to nsd
.
If you get java.lang.module.FindException: Module <module name> not found
error, open the file in a text editor, locate the problematic module and remove it from the --add-modules
list.
Version: |
-org.nasdanika.html.model.app.gen.cli@2024.4.0
+org.nasdanika.html.model.app.gen.cli@2024.5.0
|
---|
@@ -160,7 +160,7 @@