Last updated April 15, 2003
if (registry is already resolved)
stop now – nothing to do
foreach (plugin in the registry) do {
if (the plugin is missing any of the required fields)
generate an error and disable this plugin
make an IndexEntry for this plugin id (if one doesn’t exist)
put this plugin in the version list of this IndexEntry in order from largest down
} end foreach
foreach (fragment in the registry) do {
if (the fragment is missing any of the required fields)
generate an error and ignore this fragment
make sure all prerequisites for this fragment exist (bug 10799)
find the plugin for fragment.getPluginId() + fragment.getPluginVersion() using
the matching rules described in class PluginVersionIdentifier (bug 5668)
if (the plugin is not found)
generate an error and ignore this fragment
add this fragment to the plugin’s list of fragments (plugin.fragments)
} end foreach
foreach (plugin in the registry) do {
foreach (fragment in this plugin’s fragment list) do {
if (this is the most recent version of this fragment in this list)
add the components of this fragment to this plugin
if (this fragment adds a library to the plugin)
make sure we don’t have duplicate library entries in the plugin (bug 23522)
} end foreach
remove any fragments not contributing to the plugin (i.e. older versions of a fragment) (bug 10719 and 10720)
} end foreach
identify all the root plugin ids
foreach (root plugin id) do {
identify the latest version of the root and use it only
build the ConstraintsEntry -> Constraints structure under this IndexEntry
recursively build these structures for each prerequisite
} end foreach
NOTE: When the above foreach is done, each plugin id will have an associated IndexEntry -> ConstraintsEntry -> Constraints structure. For a given plugin id, the associated IndexEntry, etc. will identify all plugins which require this one as a prerequisite and all conditions which much be satisfied. The building of these structures must also remove any prerequisite loops and remove any conflicts. This may require disabling some plugins and removing portions of the ConstraintsEntry -> Constraints structure under a particular IndexEntry.
foreach (IndexEntry) do {
foreach (ConstraintsEntry) do {
find the plugin descriptor that is a best match for this group of Constraints
} end foreach (ConstraintsEntry)
} end foreach (IndexEntry)
disable all plugin descriptors
foreach (IndexEntry) do {
foreach (ConstraintsEntry) do {
enable the plugin found to be the best match in the previous loop
find the PluginPrerequisite that this plugin descriptor satisfies
tell the PluginPrerequisite which version we resolved to
} end foreach (ConstraintsEntry)
} end foreach (IndexEntry)
optional – remove all disabled plugins from the registry
optional
foreach (enabled plugin in the registry) do {
foreach (extension in this plugin) do {
find the associated extension point
if (extension point not found){
generate an error
NOTE: Should the plugin be disabled?
} endif
add this extension to the list of extensions for the found extension point
} end foreach (extension)
} end foreach (enabled plugin)
end optional
A plugin with no extensions or extension points is termed a ‘library’ plugin.
Version Numbers are matched as follows:
Example (all plugins are library plugins):
Resolving will give us the following plugins:
Ideally, pluginB could have used pluginC version 2.0.5.
If a conflict arises such that a particular subtree becomes orphaned, the root of this subtree will be considered a root node and the remainder of the subtree (if it resolves correctly) will remain intact. Consider the following example (pluginResolveTest_15):
PluginA 1.2.0 requires PluginB 2.1.0 and PluginC 1.0.0
PluginB 1.0.0 has no requirements but does have an extension and extension point
PluginB 2.1.0 requires PluginC 2.0.5 (exact match)
PluginC 1.0.0 has no requirements
PluginC 1.1.0 has no requirements but have an extension and extension point
PluginC 2.0.5 has no requirements
In this case, a conflict (non-resolvable because of extensions and extension points) exists in PluginA and it is disabled. This causes PluginB to be orphaned and it is then considered a root. Resolution of the above example will return a registry containing PluginB 2.1.0 and PluginC 2.0.5. While this may seem counter-intuitive, consider the case where PluginA was a PDE plugin and PluginB was the JDT plugin. JDT can live without PDE and the subtree really should survive the conflict in PDE’s plugin.
We now have the notion of prerequisites which are optional, called soft prerequisites. These prerequisites must have the clause ‘optional=”true”’. Consider the following xml statement:
<requires> <import plugin="tests.c" version="2.1.0" optional=”true”/> </requires>
This prerequisite will be ignored if any of the following conditions apply:
If an optional prerequisite is ignored for any of the reasons listed above no error message is generated (but an informational message may be output to indicate that this prerequisite is being ignored). Ignoring an optional prerequisite does not cause any plugins to be disabled. This causes potential error conditions to be more complex. Each time we have a situation where we have a conflict, we must first check to see if this is an optional prerequisite. The same is true of situations where we expect to find an associated IndexEntry (or other structure).
If a prerequisite is ignored, the Constraint structure associated with this particular parent/prerequisite pair is not added into the IndexEntry, ConstraintsEntry, Constraint structure. None of the existing structures or pointers to them are altered or removed. We cannot tell, without re-examining every relationship associated with this particular root plugin, which portions were used for other relationships (and not just the relationship leading to this ignored prerequisite).
The ConstraintsEntry structure contains a field called ‘lastResolved’ which is set but does not seem to be used. At the same time, there are numerous places where we examine all of the Constraints off a ConstraintsEntry structure to determine which plugin (if any) is the best one to resolve these Constraints compatibly. Can we use ‘lastResolved’ to try and minimize these? Each time we look for a best match plugin, we cycle through all versions of this plugin and all Constraints off this ConstraintsEntry.