10 KiB
[ Main Table Of Contents | Table Of Contents | Keyword Index ]
NAME
punk::cap - capability provider and handler plugin system
Table Of Contents
SYNOPSIS
package require punk::cap
class::interface_caphandler.registry pkg_register pkg capname capdict fullcapabilitylist
class::interface_caphandler.registry pkg_unregister pkg
class::interface_capprovider.registration get_declarations
class::interface_capprovider.provider constructor providerpkg
class::interface_capprovider.provider register ?capabilityname_glob?
class::interface_capprovider.provider capabilities
capability_exists capname
capability_has_handler capname
capability_get_handler capname
advanced::promote_provider pkg
advanced::demote_provider pkg
DESCRIPTION
Overview
punk::cap provides management of named capabilities and the provider packages and handler packages that implement a pluggable capability.
Concepts
A capability may be something like providing a folder of files, or just a data dictionary, and/or an API
capability handler - a package/namespace which may provide validation and standardised ways of looking up provider data registered (or not) using register_capabilityname
capability provider - a package which registers as providing one or more capablities.
registered using register_package the capabilitylist is a list of 2-element lists where the first element is the capabilityname and the second element is a (possibly empty) dict of data relevant to that capability A capabilityname may appear multiple times. ie a package may register that it provides the capability with multiple datasets.
API
Namespace punk::cap::class
class definitions
-
handler_classes
-
CLASS interface_caphandler.registry
-
CLASS interface_caphandler.sysapi
-
-
provider_classes
-
CLASS interface_cappprovider.registration Your provider package will need to instantiate this object under a sub-namespace called capsystem within your package namespace.
If your package namespace is mypackages::providerpkg then the object command would be at mypackages::providerpkg::capsystem::capprovider.registration
Example code for your provider package to evaluate within its namespace:
namespace eval capsystem { if {[info commands capprovider.registration] eq ""} { punk::cap::class::interface_capprovider.registration create capprovider.registration oo::objdefine capprovider.registration { method get_declarations {} { set decls [list] lappend decls [list punk.templates {relpath ../templates}] lappend decls [list another_capability_name {somekey blah key2 etc}] return $decls } } } }
The above example declares that your package can be registered as a provider for the capabilities named 'punk.templates' and 'another_capability_name'
-
class::interface_capprovider.registration get_declarations
This method must be overridden by your provider using oo::objdefine cappprovider.registration as in the example above. There must be at least one 2-element list in the result for the provider to be registerable.
The first element of the list is the capabilityname - which can be custom to your provider/handler packages - or a well-known name that other authors may use/implement.
The second element is a dictionary of keys specific to the capability being implemented. It may be empty if the any potential capability handlers for the named capability don't require registration data.
-
-
CLASS interface_capprovider.provider
Your provider package will need to instantiate this directly under it's own namespace with the command name of provider
namespace eval mypackages::providerpkg { punk::cap::class::interface_capprovider.provider create provider mypackages::providerpkg }
-
class::interface_capprovider.provider constructor providerpkg
-
class::interface_capprovider.provider register ?capabilityname_glob?
This is the mechanism by which a user of your provider package will register your package as a provider of the capability named.
A user of your provider may elect to register all your declared capabilities:
package require mypackages::providerpkg mypackages::providerpkg::provider register *
Or a specific capability may be registered:
package require mypackages::providerpkg mypackages::providerpkg::provider register another_capability_name
-
class::interface_capprovider.provider capabilities
return a list of capabilities supported by this provider package
-
-
Namespace punk::cap
Main punk::cap API for client programs interested in using capability handler packages and associated (registered) provider packages
-
Return a boolean indicating if the named capability exists (0|1)
-
capability_has_handler capname
Return a boolean indicating if the named capability has a handler package installed (0|1)
-
capability_get_handler capname
Return the base namespace of the active handler package for the named capability.
The base namespace for a handler will always be the package name, but prefixed with ::
Namespace punk::cap::advanced
punk::cap::advanced API. Functions here are generally not the preferred way to interact with punk::cap.
In some cases they may allow interaction in less safe ways or may allow use of features that are unavailable in the base namespace.
Some functions are here because they are only marginally or rarely useful, and they are here to keep the base API simple.
-
advanced::promote_provider pkg
Move the named provider package to the preferred end of the list (tail).
The active handler may or may not utilise this for preferencing. See documentation for the specific handler package to confirm.
promote/demote doesn't always make a lot of sense .. should preferably be configurable per capapbility for multicap provider pkgs
The idea is to provide a crude way to preference/depreference packages independently of order the packages were loaded e.g a caller or cap-handler can ascribe some meaning to the order of the 'providers' key returned from punk::cap::capabilities
The order of providers will be the order the packages were loaded & registered
the naming: "promote vs demote" operates on a latest-package-in-list has higher preference assumption (matching last pkg loaded)
Each capability handler could and should implement specific preferencing methods within its own API if finer control needed. In some cases the preference/loading order may be inapplicable/irrelevant to a particular capability anyway.
As this is just a basic mechanism, which can't support independent per-cap preferencing for multi-cap packages - it only allows putting the pkgs to the head or tail of the lists.
Whether particular caps or users of caps do anything with this ordering is dependent on the cap-handler and/or calling code.
-
Move the named provider package to the preferred end of the list (tail).
The active handler may or may not utilise this for preferencing. See documentation for the specific handler package to confirm.
Internal
Namespace punk::cap::capsystem
Internal functions used to communicate between punk::cap and capability handlers
COPYRIGHT
Copyright © 2023 JMNoble - BSD licensed