| <html> |
| <head><title>Planned changes to the plug-in registry APIs and their implementation</title></head> |
| <body> |
| <h1>Planned changes to the plug-in registry API and implementation</h1> |
| <EM>Last update: April 23, 2003</EM> |
| <h4>Summary of planned changes:</h4> |
| |
| <ul> |
| <li><a href="#fragments_api">Provide API for fragments in the platform registry</a></li> |
| <li><a href="#fragments_nls">Provide modular way to externalize strings in fragment.xml</a></li> |
| <li><a href="#contributed_elements">Provide API for checking if a given plug-in descriptor element has been contributed by a fragment</a></li> |
| </ul> |
| |
| <h3><a name="fragments_API">Provide API for fragments in the platform registry</a></h3> |
| |
| <h4>Related bugs:</h4> |
| <ul> |
| <li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14460">Bug 14460</a> |
| - [runtime] No APIs for obtaining fragments installation directory for a given plugin</li> |
| <li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20499">Bug 20499</a> |
| - Need a public API similer to FragmentDescriptor#getInstallURL()</li> |
| </ul> |
| |
| <p>The platform registry API, whose starting point is the <code>Platform.getPluginRegistry()</code>, |
| provides access to descriptors for the plug-ins in the registry but not for the fragments. Fragments |
| provide objects (pre-requisites, libraries, extensions, extension points) that are combined with those |
| in the plug-in they associate to during the registry resolution process.</p> |
| |
| <h4>Requisites:</h4><ul> |
| <li>the install URL for a fragment is needed: the general use case is that plug-in's/fragment's code |
| need to know the location of specific files contributed by fragments.</li> |
| </ul> |
| |
| <h4>Proposed solution:</h4><ul> |
| <li>add new API interface <code>org.eclipse.core.runtime.IFragmentDescriptor</code>;</li> |
| <li>add new API method <code>URL[] getInstallURL()</code> to |
| <code>IFragmentDescriptor</code>;</li> |
| <li>add new API methods <code>IFragmentDescriptor[] getFragments()</code> and |
| <code>IFragmentDescriptor getFragment(String id)</code> |
| to <code>IPluginDescriptor</code>.</li> |
| </ul> |
| |
| <h4>Notes:</h4> |
| <p>Currently, clients rely on the fact that the implementations for plug-in registry interfaces in |
| <code>org.eclipse.core.runtime</code> extend the corresponding model classes in |
| <code>org.eclipse.core.runtime.model</code>. This is not specified - we should document if this |
| is expected or disallowed (and we would be able to change the implementation hierarchy for those classes). |
| </p> |
| |
| <h3><a name="fragments_NLS">Provide modular way to externalize strings in fragment.xml</a></h3> |
| |
| <h4>Related bugs:</h4><ul> |
| <li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18617">Bug 18617</a> |
| - [runtime] modular way to externalize strings in fragment.xml</li> |
| <li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18339">Bug 18339</a> |
| - API clarification: where to find translations for labels and provider names for plug-ins and fragments</li> |
| <li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31094">Bug 31094</a> |
| - [About] show real plugin names in 'About'</li> |
| <li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31596">Bug 31596</a> |
| - fragment_*.properties should participate in the plugin resource bundle find path</li> |
| <li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35992">Bug 35992</a> |
| - [runtime] Fragments should know their plug-ins</li> |
| </ul> |
| |
| <p>From Jeem's comments in bug 18617:</p> |
| |
| <p><cite>"Externalized strings for all plug-in fragments must be placed in the |
| their plug-in's "plugin.properties" resource bundle. In other words, |
| a fragment's strings must be merged into the main plug-in's file. |
| Although this is not very modular, it does at least allow strings |
| to be externalized and translated."</cite></p> |
| |
| |
| <h4>Requisites:</h4><ul> |
| <li>UI needs to translate fragment name and fragment's provider name to show in the about dialog (bug 31094).</li> |
| <li>fragments should be able to have their externalized strings provided by |
| themselves, by the plug-in, or by other fragments (bugs 18617, 31596).</li> |
| </ul> |
| |
| <h4>Proposed solution:</h4> |
| |
| <p>From Jeem's comments in bug 18617:</p> |
| |
| <p><cite>"In order to dovetail with existing mechanisms, each fragment must have its |
| own *.properties files. It would be a non-started if these *.properties |
| files all had the same name (e.g., "fragment.properties"), since all |
| OS-specific fragments would collide on this name making it impossible |
| to spuuly translations for any of they. It is therefore essential that each |
| fragment get a distinctively named *.properties file. The simplest way to |
| arrange this is to add a new attribute to the <fragment> element |
| to specific the name of the properties file; e.g., |
| resource-bundle="win32fragment" |
| would mean that the file named "win32fragment.properties" would contain |
| the translated strings ("win32fragment" is the base name of the property |
| resource bundle, in Java parlance). </cite></p> |
| |
| <p><cite>The attribute would also be meaningful on a <plugin> element. If the attribute |
| is omitted, the default resource bundle base name is "plugin". This makes |
| the new story upwards compatible with the current story where all "%vars" |
| in the plugin.xml and in all the fragment.xmls get resolved in the plug-in's |
| property resource bundle "plugin.properties"."</cite></p> |
| |
| <p>Methods in the model objects return strings as they appear in the manifest file. |
| Clients that want those strings properly translated should (as suggested in bug 18339) |
| call <code>IPluginDescriptor#getResolvedString(String)</code> |
| and the new proposed method <code>IFragmentDescriptor#getResolvedString(String)</code>.</p> |
| |
| <p>Also, since the ".properties" file may be anywhere in th plug-in's |
| classpath, the fragment descriptor implementation should ask its plug-in descriptor |
| for the path where to look for it (what requires a fix for bug 35992).</p> |
| <ul> |
| |
| <li>add new API methods <code>String getLabel()</code>, <code>String getProviderName()</code> |
| and <code>String getResourceString(String)</code> to <code>IFragmentDescriptor</code> |
| - these methods would do the same thing as their counterparts in <code>IPluginDescriptor</code> |
| but would take into consideration the bundle built on the corresponding <code>fragment.properties</code> |
| file;</li> |
| <li>the internal implementation for <code>IPluginDescriptor</code> should be |
| refactored in order to share the translation funcionality with the new method |
| <code>getResourceString(String)</code> to be implemented by <code>FragmentDescriptor</code>.</li> |
| </ul> |
| |
| <h3><a name="contributed_elements">Provide API for checking if a given plug-in descriptor element has been contributed by a fragment</a></h3> |
| |
| <h4>Related bugs:</h4><ul> |
| <li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23165">Bug 23165</a> |
| - [runtime] Plug-in model objects should know where they are coming from</li> |
| </ul> |
| |
| <p>Fragments provide objects (pre-requisites, libraries, extensions, extension |
| points) that are combined with those in the plug-in they associate to during |
| the registry resolution process.</p> |
| |
| <h4>Requisites:</h4><ul> |
| |
| <li>it should be possible to tell apart elements provided by plug-ins from those |
| contributed by fragments: PDE currently casts the <code>IPluginRegistry</code> |
| and <code>IPluginDescriptor</code> to their corresponding model objects (already |
| in memory) to avoid reparsing the manifests. But since the registry is already |
| resolved, PDE does not know which elements were originally part of a plug-in. |
| A simple <code>isFragmentContributed()</code> (in a sense that it is contributed |
| by a fragment) in library, pre-requisite, extension and extension point model |
| objects would be enough. To reduce memory footprint, the <code>PluginModelObject.flags</code> |
| field could be used to store this information.</li> |
| </ul> |
| |
| <h4>Proposed solution:</h4><ul> |
| <li>add new API class <code>FragmentContributableModel</code> (sub-class of <code>PluginModelObject</code>);</li> |
| <li>add new API methods <code>boolean FragmentContributableModel.isFragmentContributed()</code> and <code>void FragmentContributableModel.markFragmentContributed()</code>;</li> |
| <li>make <code>LibraryModel</code>, <code>PrerequisiteModel</code>, <code>ExtensionModel</code> and <code>ExtensionPointModel</code> sub-classes of <code>FragmentContributableModel</code>;</li> |
| <li>make <code>PluginModelObject.flags</code> package-private so they can be |
| accessed from <code>FragmentContributableModel</code>.</li> |
| </ul> |
| |
| </body> |
| </html> |