Purpose - to provide the mechanisms to load (and unload) the auxiliary
modules.
The Module loader is located in
org.argouml.moduleloader.
It is the modules' responsibility to connect and register to the
subsystem or subsystems it is going to work with using that subsystem's API,
Facade, or Plug-in interface.
A previous implemention of the module loader was located in
org.argouml.application.modules.ModuleLoader
with interfaces (Pluggable) in
org.argouml.application.api, but it has been
replaced by the interface described here.
For details on how to build a module see Section 6.2, “Modules ”.
5.21.1. What the ModuleLoader does
The ModuleLoader looks for module jars. It scans
through all jars available in the ext directory. See Edit Settings
Environment tab. If you turn on logging on the debug level while running
ArgoUML you should be able to see what jar files it finds and what it does
with them.
A module jar contains the classes, resources and a manifest file. The
manifest file points out the class to be loaded. Also notice that the
Specification-Title and Vendor must be specified correctly for this to
work. [What does "correctly" mean in this context?]
5.21.2. Design of the Module Loader
Design:
We use a Loadable Proxy Pattern(?) for the modules.
Each module can be enabled and disabled individually.
Dependencies between modules are allowed although not yet handled
gracefully.
Each module is required to have one (1) class that implements
ModuleInterface. That class (and all
other classes that constitute the module) needs to be made
available for some class loader, either by including it in the
classpath or by letting the module loader hunt for it.
The modules are allowed to use all the APIs available from all
the subsystems within ArgoUML and from other modules.
This is a big improvement over the old module loader in that:
We use the same APIs for the modules that we use within
ArgoUML meaning that we implement and document it only once.
This replaces the Pluggable class at every point where
ArgoUML can be augmented.
We can have the module have different classes to
register at different parts of ArgoUML.
We can have dynamic registrations that the module add
and remove over time depending on some criteria that the
module decides.
We don't need to search through all modules at every
possible point where ArgoUML can be augmented.
Just as in the old solution, whenever a module
needs to do something to ArgoUML, there needs to be implemented an
API, possibly with registration/deregistration and callbacks.
All modules that can be found are examined at startup. They can
be enabled and disabled individually from a special available
modules window but have a default state that applies if the user
hasn't taken action. Currently the default state is "enabled".
Dependency between modules!
If a module cannot be enabled because some other module needs
to be enabled first or because some part of ArgoUML needs to be
initialized first this is a problem. This is because the initial
implementation is such that we have no register of dependencies.
The solution suggested is that the module loader persists in
its attempts to enable a module so that the order among the modules
is not important. For this to work the modules needs to signal when
they fail. This is done by returning false or throwing an Exception
from the module enabling method.
The module loader also provides an API that the well-behaving
modules can use to test if the modules they depend on are enabled.
The less well-behaving modules can just throw an exception when
they fail to enable themselves properly.
If a module cannot be disabled, because some other module
depends on it then this is signaled by returning false from the
disabling method.
Where modules are loaded from?
The modules are loaded from the same places as in the old module
loader. They can be internally i.e. available in the core jar file
of ArgoUML, from the
ext directory, or if running from JavaWebStart, they
can be downloaded from the site.
To reduce the complexity of the downloads, let's use it in the
simplest possible way: organize each module in a package and a jar
file, have the jnlp-file list that jar file as a part and a package
entry listing the classes, have a file listing optional classes
and a GUI that allows the user to download them. Once a class is
selected in the GUI it is loaded and, the JavaWebStart class loader
will guarantee that it is available.
The scope of the modules.
Modules are always enabled and disabled on a per-application
(per jvm) basis and not on a per-project or per-frame basis.