SNAP includes a number of common utility components that support plugin development. For SNAP we reuse and extend the same extensibility design concept that has been used for BEAM and NEST and that is a commonly accepted object-oriented design pattern for enterprise applications. It works as follows:
A module provides the code for one or more plugins. As described in the section on the High-Level Architecture, modules can be dynamically installed and updated. If a module is installed or updated, new plugins are registered in the system or existing ones are replaced by new versions. If a module is uninstalled, its plugins are removed from the platform. Plugin management takes place as part of a module’s life cycle which is controlled by the platform and which is transparent to the module developer. When a plugin is declared in a module, the platform can recognize it. For the GUI we use the well documented, elaborated, and powerful NetBeans Platform extension concept (see The NetBeans Platform [https://netbeans.org/features/platform/]). For SNAP Engine modules we only use the basic, widely known JAR SPI concept (see Creating Extensible Applications, [https://docs.oracle.com/javase/tutorial/ext/basics/spi.html]), as we do not want any dependencies from the SNAP Engine to SNAP desktop.
A plugin is a software component that adheres to the contract of a service provider interface (SPI). The abstract SPIs are part of the APIs exposed by SNAP. The following abstract SPIs are part of the SNAP API and defined for the following plugins:
- Data Reader plugins used to read/ingest data from external sources into an in-memory PDM instance which then continues to use the reader to load data when requested (data subsystem)
- Data Processor plugins that transform a source PDM instance into a new target PDM instance or modify the source
- Data Writer plugins that transform a PDM instance into any external data types and formats. This is useful for saving or exporting or otherwise representing whole or partial PDM instances.
- Actions (appearing in menus and toolbars), diagram or 2D/3D-image views, tool windows (dockable editor windows for selected PDM nodes or views), preferences pages plugins, etc. that provide extensions to the GUI or command-line option plugins that provide extensions to the CLI
As the name indicates, a concrete SPI is a factory and sometimes a proxy for the actual service to be used in the software. For example, the data reader SPI defines at least two abstract method that a concrete SPI implementation must provide. One method checks if a given input object (file pointer, stream, URL) can be opened and interpreted by this type of data reader. The second - the factory method - instantiates the actual reader service for the given input object, including optional parameterisation, which is finally used to read from the input object.
Available plugins are detected on start-up time of the Sentinel Toolbox and automatically made available to other application modules by dedicated plugin registries. The application can then populate, e.g., a processor library tool window or the data import/export menus. During application runtime plugin-providing modules can be updated, added or removed from the application using the plugin manager of the Sentinel Toolbox.
In addition to extending SNAP via plugins, it is also possible using the SNAP libraries for use in other applications. For instance, a developer might want to write software that makes direct use of SNAP functions via the platform APIs. Both use cases, namely Toolbox reuse and toolbox extension are shown in the following figure:
Use case #2 indicates that the toolbox allows extensions to use both native Python and Java plugins. "Native" means that programmers can use a dedicated API using maximum runtime performance and data transfer rate. It also allows to invoke any other external executable, e.g. as a node in a processing graph or invoked from the Toolbox GUI. Use case #1 is the use of existing platform libraries (including extensions) via Python and Java in client software.
Python and R APIs
SNAP provides a native Python bridge, which makes it possible to (a) use the SNAP libraries and its Java plugins from Python and (b) to implement SNAP processor extensions in Python. The SNAP Python Bridge also allows for the use of R (via the Python rpy2 module). As processor plugins can be written in Python, it is straight forward to implement a Python processor that makes use of R code.
Wrapper APIs for Python and R enable developers to access the Sentinel Toolbox capabilities and services programmatically from their own code and analysis workflows. For example, the data access functions return Python-specific data arrays for Python while internally they use the modules implemented in Java.
Stand-Alone Tools Adapter
The Sentinel Toolbox can and will not solve all user needs. Users will still wish to utilize other tools that are external to the Toolbox and that either provide functionality not provided by the Toolbox or that implement a desired functionality in a different way. In many cases, it is more comfortable and more effective if users can stay in one environment. SNAP lets users (a) integrate their desired external tools into the Toolbox, and (b) add external tools to the Toolbox' standard configuration. This is useful for tools that have already been developed and which would be difficult or impossible to be reengineered as Sentinel Toolbox plugins.
The Stand-Alone Tools Adapter is the glue between the Toolbox and the external tool’s user interface. The four major responsibilities for the Stand-Alone Tools Adapter are:
- Provide the user’s inputs from the Toolbox context to the external tool;
- Invoke the tool so that a new process is created;
- Notify the user about the progress and eventually let her/him cancel the running process;
- Open the generated outputs in the Toolbox.